{"id":35699323,"url":"https://github.com/dicklesworthstone/ultimate_bug_scanner","last_synced_at":"2026-05-13T06:10:19.506Z","repository":{"id":324518946,"uuid":"1097502375","full_name":"Dicklesworthstone/ultimate_bug_scanner","owner":"Dicklesworthstone","description":"Static analysis tool that catches 1000+ bug patterns across all popular programming languages, with auto-wiring into AI coding agent quality guardrails","archived":false,"fork":false,"pushed_at":"2026-04-25T03:31:54.000Z","size":18054,"stargazers_count":216,"open_issues_count":0,"forks_count":32,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-04-25T03:38:48.281Z","etag":null,"topics":["agent-tools","ai-agents","bash","bugs","cli","code-quality","developer-tools","linting","static-analysis"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Dicklesworthstone.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"docs/security.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2025-11-16T10:01:59.000Z","updated_at":"2026-04-25T03:31:58.000Z","dependencies_parsed_at":"2026-03-06T06:16:00.930Z","dependency_job_id":null,"html_url":"https://github.com/Dicklesworthstone/ultimate_bug_scanner","commit_stats":null,"previous_names":["dicklesworthstone/ultimate_bug_scanner"],"tags_count":16,"template":false,"template_full_name":null,"purl":"pkg:github/Dicklesworthstone/ultimate_bug_scanner","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dicklesworthstone%2Fultimate_bug_scanner","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dicklesworthstone%2Fultimate_bug_scanner/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dicklesworthstone%2Fultimate_bug_scanner/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dicklesworthstone%2Fultimate_bug_scanner/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Dicklesworthstone","download_url":"https://codeload.github.com/Dicklesworthstone/ultimate_bug_scanner/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dicklesworthstone%2Fultimate_bug_scanner/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32476682,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-30T13:12:12.517Z","status":"ssl_error","status_checked_at":"2026-04-30T13:12:06.837Z","response_time":57,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agent-tools","ai-agents","bash","bugs","cli","code-quality","developer-tools","linting","static-analysis"],"created_at":"2026-01-06T01:11:57.469Z","updated_at":"2026-05-13T06:10:19.491Z","avatar_url":"https://github.com/Dicklesworthstone.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# 🔬 Ultimate Bug Scanner v5.0\n\n\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"docs/assets/ubs_illustration.webp\" alt=\"Ultimate Bug Scanner - The AI Coding Agent's Secret Weapon\"\u003e\n\u003c/div\u003e\n\n### **The AI Coding Agent's Secret Weapon: Flagging Likely Bugs for Fixing Early On**\n\n[![License: MIT](https://img.shields.io/badge/License-MIT%2BOpenAI%2FAnthropic%20Rider-blue.svg)](./LICENSE)\n[![Platform](https://img.shields.io/badge/platform-Linux%20%7C%20macOS%20%7C%20Windows-blue.svg)](https://github.com/Dicklesworthstone/ultimate_bug_scanner)\n[![Version](https://img.shields.io/badge/version-5.2.69-blue.svg)](https://github.com/Dicklesworthstone/ultimate_bug_scanner)\n\n\u003cdiv align=\"center\"\u003e\n\n```bash\n# One command to catch 1000+ bug patterns (always main, cache-busted)\ncurl -fsSL \"https://raw.githubusercontent.com/Dicklesworthstone/ultimate_bug_scanner/main/install.sh?$(date +%s)\" \\\n  | bash -s --\n```\n\n**Or via Homebrew (macOS/Linux):**\n\n```bash\nbrew install dicklesworthstone/tap/ubs\n```\n\n\u003c/div\u003e\n\n---\n\nJust want it to do everything without confirmations? Live life on the edge with easy-mode to auto-install every dependency, accept all prompts, detect local coding agents, and wire their quality guardrails with zero extra questions:\n\n\u003cdiv align=\"center\"\u003e\n\n```bash\ncurl -fsSL \"https://raw.githubusercontent.com/Dicklesworthstone/ultimate_bug_scanner/main/install.sh?$(date +%s)\" \\\n  | bash -s -- --easy-mode\n```\n\nNote: Windows users must run the installer one-liner from within Git Bash, or use WSL for Windows. \n\n\u003c/div\u003e\n\n---\n\n## 🤖 Agent Quickstart (JSON/TOON)\n\n**Use machine-readable output in agent contexts.** stdout = data, stderr = diagnostics, exit 0 = success.\n\n```bash\n# Scan current repo (JSON)\nubs . --format=json\n\n# Token-optimized output (TOON)\nubs . --format=toon\n\n# Scan only staged changes\nubs --staged --format=json\n\n# CI-strict (fail on warnings)\nubs . --profile=strict --fail-on-warning --format=json\n```\n\n## 💥 **The Problem: AI Moves Fast, Bugs Move Faster**\n\nYou're coding faster than ever with Claude Code, Codex, Cursor, and other AI coding agents. You're shipping features in minutes that used to take days. **But here's the painful truth:**\n\n### **Even the best AI makes these mistakes:**\n\n**JavaScript/TypeScript example** *(similar patterns exist in Python, Go, Rust, Java, C++, Ruby)*:\n\n```javascript\n// ❌ CRITICAL BUG #1: Null pointer crash waiting to happen\nconst submitButton = document.getElementById('submit');\nsubmitButton.addEventListener('click', handleSubmit);  // 💥 Crashes if element doesn't exist\n\n// ❌ CRITICAL BUG #2: XSS vulnerability\nfunction displayUserComment(comment) {\n  document.getElementById('comments').innerHTML = comment;  // 🚨 Security hole\n}\n\n// ❌ CRITICAL BUG #3: Silent failure (missing await)\nasync function saveUser(data) {\n  const result = validateUser(data);  // 💥 Should be 'await validateUser(data)'\n  await saveToDatabase(result);  // Saves undefined!\n}\n\n// ❌ CRITICAL BUG #4: Always false comparison\nif (calculatedValue === NaN) {  // 💥 This NEVER works (always false)\n  console.log(\"Invalid calculation\");\n}\n\n// ❌ CRITICAL BUG #5: parseInt footgun\nconst zipCode = parseInt(userInput);  // 💥 \"08\" becomes 0 in old browsers (octal!)\n```\n\n**Each of these bugs could cost 3-6 hours to debug in production.** Similar issues plague every language: unguarded null access, missing `await`, security holes from `eval()`, buffer overflows from `strcpy()`, `.unwrap()` panics, goroutine leaks... **You've probably hit all of them.**\n\n---\n\n## 🎯 **The Solution: Your 24/7 Bug Hunting Partner**\n\n### 🧠 Language-Aware Meta-Runner\n- `ubs` auto-detects **JavaScript/TypeScript, Python, C/C++, Rust, Go, Java, Ruby, Swift, C#, and Elixir** in the same repo and fans out to per-language scanners.\n- Each scanner lives under `modules/ubs-\u003clang\u003e.sh`, ships independently, and supports `--format text|json|jsonl|sarif|toon` for consistent downstream tooling.\n- Modules download lazily (PATH → repo `modules/` → cached under `${XDG_DATA_HOME:-$HOME/.local/share}/ubs/modules`) and are validated before execution.\n- Results from every language merge into one text/JSON/SARIF report via `jq`, so CI systems and AI agents only have to parse a single artifact.\n\n### 🔐 Supply-Chain Safeguards\n- Every lazily-downloaded module (and its helper assets) ships with pinned SHA-256 checksums baked into the meta-runner. Files fetched from GitHub are verified before they can execute, preventing tampering between releases.\n- The cache lives under `${XDG_DATA_HOME:-$HOME/.local/share}/ubs/modules` by default; use `--module-dir` to relocate it (e.g., inside a CI workspace) while retaining the same verification guarantees.\n- Run `ubs doctor` at any time to audit your environment. It checks for curl/wget availability, writable cache directories, and per-language module integrity. Add `--fix` to redownload missing or corrupted modules proactively.\n- Scanner runs still respect `--update-modules`, but an invalid checksum now causes an immediate failure with remediation guidance rather than executing unverified code.\n- **Developer Pre-commit Hook**: The repository ships with a `.githooks/pre-commit` hook that auto-updates `SHA256SUMS` when modules change and blocks commits with stale checksums. This ensures every release has verified checksums without manual intervention.\n- **Minisign Support**: For additional assurance, set `UBS_MINISIGN_PUBKEY` to verify cryptographic signatures on `SHA256SUMS` via [minisign](https://jedisct1.github.io/minisign/).\n\n### 🎛 Category Packs \u0026 Shareable Reports\n- `--category=resource-lifecycle` focuses the scanners on Python/Go/Java resource hygiene (context managers, defer symmetry, try-with-resources). UBS automatically narrows the language set to those with lifecycle packs enabled and suppresses unrelated categories.\n- `--comparison=\u003cbaseline.json\u003e` diff the latest combined summary against a stored run. Deltas feed into console output, JSON, HTML, and SARIF automation metadata so CI can detect regressions.\n- `--report-json=\u003cfile\u003e` writes an enriched summary (project, totals, git metadata, optional comparison block) that you can archive or share with teammates/CI.\n- `--html-report=\u003cfile\u003e` emits a standalone HTML preview showing totals, trends vs. baseline, and per-language breakdowns—ideal for attaching to PRs or chat updates.\n- All shareable outputs inject GitHub permalinks when UBS is run inside a git repo with a GitHub remote. Text output automatically annotates `path:line` references, JSON gains `git.*` metadata, and merged SARIF runs now include `versionControlProvenance` plus `automationDetails` keyed by the comparison id.\n\n#### Resource lifecycle heuristics in each language\n- **Python** – Category 16 now correlates every `open()` call against matching `with open(...)` usage and explicit `encoding=` parameters, while Category 19 uses the new AST helper at `modules/helpers/resource_lifecycle_py.py` to walk every file, socket, subprocess, asyncio task, and context cancellation path. The helper resolves alias imports, context managers, and awaited tasks so the diff counts (`acquire=X, release=Y, context-managed=Z`) show the exact imbalance per file.\n- **Go** – Category 5/17 now run a Go AST walker (`modules/helpers/resource_lifecycle_go.go`) that detects `context.With*` calls missing cancel, `time.NewTicker/NewTimer` without `Stop`, `os.Open/sql.Open` without `Close`, and mutex `Lock`/`Unlock` symmetry. Category 9 also tracks request query/header/form/framework values into response headers unless they strip or reject CR/LF, tracks redirect targets into `http.Redirect`, framework `Redirect` calls, and `Location` headers unless they pass through same-origin or explicit allow-list validation, flags request-derived reverse proxy targets flowing into `httputil.NewSingleHostReverseProxy`, `ProxyRequest.SetURL`, or `Director` URL mutation without HTTPS plus host allow-list validation, flags request-derived SQL text flowing into `ExecContext`/`QueryContext`, sqlx-style helpers, or query-builder predicates unless request data is passed as bound parameters, flags credentialed wildcard or reflected-origin CORS responses, and catches auth/session cookies missing `HttpOnly`, `Secure`, or `SameSite` protections. Findings come straight from the AST/resource helper or taint pass positions, so “ticker missing Stop()” and header/open-redirect/reverse-proxy/CORS/cookie/SQL lines map to exact `file:line` references instead of coarse regex summaries.\n- **Java / Kotlin** – Category 5 surfaces `FileInputStream`, readers/writers, JDBC handles, etc. that were created outside try-with-resources, while Category 19 keeps tracking executor services and file streams that never close. Category 4 also tracks servlet/Spring/Ktor request parameters, headers, and annotated parameters into response headers unless they strip/reject CR/LF or encode header fragments, and into redirect sinks such as `sendRedirect`, `respondRedirect`, Spring `redirect:` views, `RedirectView`, `ModelAndView`, and `Location` headers unless a same-origin or explicit allow-list helper is applied first. The summary text matches the manifest fixtures, so CI will fail if regression swallows these warnings.\n\n#### Shareable output quickstart\n```bash\n# 1) Capture a baseline JSON (checked into CI artifacts or local history)\nubs --ci --only=python --category=resource-lifecycle \\\n    --report-json .ubs/baseline.json test-suite/python/buggy\n\n# 2) Re-run with comparison + HTML preview for PRs or chat threads\nubs --ci --only=python --category=resource-lifecycle \\\n    --comparison .ubs/baseline.json \\\n    --report-json .ubs/latest.json \\\n    --html-report  .ubs/latest.html \\\n    test-suite/python/buggy\n```\n\n`latest.json` now contains the git metadata (repo URL, commit, blob_base) plus a `comparison.delta` block, and `latest.html` renders a lightweight dashboard summarising the deltas. SARIF uploads also pick up the comparison id so repeating runs in CI stay grouped by automation id.\n\n---\n\n## 💡 **Basic Usage**\n\n```bash\n# Scan current directory\nubs .\n\n# Scan specific directory\nubs /path/to/your/project\n\n# Verbose mode (show more code examples)\nubs -v .\n\n# Save report to file\nubs . bug-report.txt\n\n# CI mode (exit code 1 on warnings)\nubs . --fail-on-warning\n\n# Quiet mode (summary only)\nubs -q .\n\n# Skip specific categories (e.g., skip TODO markers)\nubs . --skip=11,14\n\n# Custom file extensions\nubs . --include-ext=js,ts,vue,svelte\n```\n\n### Handy switches\n\n```bash\n# Git-aware quick scans (changed files only)\nubs --staged    # Scan files staged for commit\nubs --diff      # Scan working tree changes vs HEAD\n\n# Strictness profiles\nubs --profile=strict   # Fail on warnings, enforce high standards\nubs --profile=loose    # Skip TODO/debug/code-quality nits when prototyping\n\n# Machine-readable output\nubs . --format=json    # Pure JSON on stdout; logs go to stderr\nubs . --format=jsonl   # Line-delimited summary per scanner + totals\nubs . --format=toon    # TOON format (~50% smaller than JSON, LLM-optimized)\nubs . --format=jsonl --beads-jsonl out/findings.jsonl  # Save JSONL for Beads/\"strung\"\n```\n\n### Keeping noise low\n- UBS auto-ignores common junk (`node_modules`, virtualenvs, dist/build/target/vendor, editor caches, etc.).\n- Inline suppression is available when a finding is intentional: `eval(\"print('safe')\")  # ubs:ignore`\n\n## 🚀 **Quick Install (30 Seconds)**\n\n### **Recommended: Homebrew (macOS/Linux)**\n\n```bash\nbrew install dicklesworthstone/tap/ubs\n```\n\nThis method provides:\n- Automatic updates via `brew upgrade`\n- Dependency management\n- Easy uninstall via `brew uninstall`\n\n### **Windows: Scoop**\n\n```powershell\nscoop bucket add dicklesworthstone https://github.com/Dicklesworthstone/scoop-bucket\nscoop install dicklesworthstone/ubs\n```\n\n### **Alternative: Automated Install**\n\n```bash\ncurl -fsSL \"https://raw.githubusercontent.com/Dicklesworthstone/ultimate_bug_scanner/main/install.sh?$(date +%s)\" | bash\n```\n\n### **Option 2: Integrity-first install (signed checksums)**\n\n```bash\nexport UBS_MINISIGN_PUBKEY=\"RWQg+jMrKiloMT5L3URISMoRzCMc/pVcVRCTfuY+WIzttzIr4CUJYRUk\"\ncurl -fsSL https://raw.githubusercontent.com/Dicklesworthstone/ultimate_bug_scanner/main/scripts/verify.sh | bash\n```\n\nThe verifier downloads `SHA256SUMS` + `SHA256SUMS.minisig` from the matching release, validates them with minisign, checks `install.sh`, and only then executes it. Use `--insecure` to bypass verification (not recommended).\n\n### **Option 3: Nix**\n\nRun directly (no install):\n\n```bash\nnix run github:Dicklesworthstone/ultimate_bug_scanner\n```\n\nDev shell for contributors:\n\n```bash\nnix develop\n```\n\n### **Option 4: Docker / OCI**\n\nPull \u0026 inspect:\n\n```bash\ndocker run --rm ghcr.io/dicklesworthstone/ubs-tools ubs --help\n```\n\nScan host code (risk-aware: grants container access to host FS):\n\n```bash\ndocker run --rm -v /:/host ghcr.io/dicklesworthstone/ubs-tools bash -c \"cd /host/path \u0026\u0026 ubs .\"\n```\n\n⚠️ Use the host-mount pattern only when you understand the write-access implications.\n\n### Deployment \u0026 Security\n\n- Release playbook (how we cut signed releases): [docs/release.md](docs/release.md)\n- Supply chain \u0026 verification model: [docs/security.md](docs/security.md)\n\nThe installer will:\n- ✅ Install the `ubs` command globally\n- ✅ Install/ensure `ast-grep` (required for accurate JS/TS scanning; UBS can auto-provision a pinned binary)\n- ✅ Optionally install `ripgrep` (for 10x faster scanning)\n- ✅ Optionally install `jq` (needed for JSON/SARIF merging across all language scanners)\n- ✅ Optionally install `typos` (smart spellchecker for docs and identifiers)\n- ✅ Optionally install `Node.js + typescript` (enables deep TypeScript type narrowing analysis)\n- ✅ Auto-run `ubs doctor` post-install and append a session summary to `~/.config/ubs/session.md`\n- ✅ Capture readiness facts (ripgrep/jq/typos/type narrowing) and store them for `ubs sessions --entries 1`\n- ✅ Set up git hooks (block commits with critical bugs)\n- ✅ Set up Claude Code hooks (scan on file save)\n- ✅ Add documentation to your AGENTS.md\n\nNeed to revisit what the installer discovered later? Run `ubs sessions --entries 1` to view the most recent session log (or point teammates at the same summary).\n\nNeed the “just make it work” button? Run the installer with `--easy-mode` to auto-install every dependency, accept all prompts, detect local coding agents, and wire their quality guardrails with zero extra questions:\n\n```bash\ncurl -fsSL \"https://raw.githubusercontent.com/Dicklesworthstone/ultimate_bug_scanner/main/install.sh?$(date +%s)\" \\\n  | bash -s -- --easy-mode\n```\n\n**Total time:** 30 seconds to 2 minutes (depending on dependencies)\n\nNeed to keep your shell RC files untouched? Combine `--no-path-modify` (and optionally `--skip-hooks`) with the command above—the installer will still drop `ubs` into your chosen `--install-dir`, but it will skip both PATH edits and the alias helper entirely.\n\n### **Option 2: Manual Install**\n\n```bash\n# Download and install the unified runner\ncurl -fsSL https://raw.githubusercontent.com/Dicklesworthstone/ultimate_bug_scanner/main/ubs \\\n  -o /usr/local/bin/ubs \u0026\u0026 chmod +x /usr/local/bin/ubs\n\n# Verify it works\nubs --help\n\n# Install dependencies (ast-grep required for JS/TS scanning)\n# Required for JS/TS scanning (syntax-aware AST engine)\nbrew install ast-grep            # or: cargo install ast-grep, npm i -g @ast-grep/cli\nbrew install ripgrep             # 10x faster searching (or: apt/dnf/cargo install)\nbrew install typos-cli           # Spellchecker tuned for code (or: cargo install typos-cli)\nnpm install -g typescript        # Enables full tsserver-based type narrowing checks\n```\n\n### **Option 3: Use Without Installing**\n\n```bash\n# Download once\ncurl -fsSL https://raw.githubusercontent.com/Dicklesworthstone/ultimate_bug_scanner/main/ubs \\\n  -o ubs \u0026\u0026 chmod +x ubs\n\n# Run it\n./ubs .\n```\n\n### Installer Safety Nets\n\n#### Uninstall from any shell\n\nRun the installer in `--uninstall` mode via curl if you want to remove UBS and all of its integrations:\n\n```bash\ncurl -fsSL \"https://raw.githubusercontent.com/Dicklesworthstone/ultimate_bug_scanner/main/install.sh?$(date +%s)\" | bash -s -- --uninstall --non-interactive\n```\n\nThis command deletes the UBS binary, shell RC snippets/aliases, config under `~/.config/ubs`, and the optional Claude/Git hooks that the installer set up. Because it passes `--non-interactive`, it auto-confirms all prompts and runs unattended.\n\n| Flag | What it does | Why it matters |\n|------|--------------|----------------|\n| `--dry-run` | Prints every install action (downloads, PATH edits, hook writes, cleanup) without touching disk. Dry runs still resolve config, detect agents, and show you exactly what *would* change. | Audit the installer, demo it to teammates, or validate CI steps without modifying a workstation. |\n| `--self-test` | Immediately runs `test-suite/install/run_tests.sh` after installation and exits non-zero if the smoke suite fails. | CI/CD jobs and verified setups can prove the installer still works end-to-end before trusting a release. |\n| `--skip-type-narrowing` | Skip the Node.js + TypeScript readiness probe **and** the cross-language guard analyzers (JS/Rust/Kotlin/Swift/C#). | Useful for air-gapped hosts or environments that want to stay in heuristic-only mode. |\n| `--skip-typos` | Skip the Typos spellchecker installation + diagnostics. | Handy when corp images already provide Typos or when you deliberately disable spellcheck automation. |\n| `--skip-doctor` | Skip the automatic `ubs doctor` run + session summary after install. | Use when CI already runs doctor separately or when you're iterating locally and want a faster finish. |\n\n\u003e [!WARNING]\n\u003e `--self-test` requires running `install.sh` from a working tree that contains `test-suite/install/run_tests.sh` (i.e., the repo root). Curl-piping the installer from GitHub can’t self-test because the harness isn’t present, so the flag will error out early instead of giving a false sense of safety.\n\n\u003e [!NOTE]\n\u003e After every install the script now double-checks `command -v ubs`. If another copy shadows the freshly written binary, you’ll get an explicit warning with both paths so you can fix PATH order before running scans.\n\n\u003e [!TIP]\n\u003e Type narrowing relies on Node.js plus the `typescript` npm package *and* the Python helpers that power the Rust/Kotlin/Swift/C# checks. The installer now checks Node/TypeScript readiness, can optionally run `npm install -g typescript`, and surfaces the status inside `install.sh --diagnose`. Use `--skip-type-narrowing` if you’re on an air-gapped host or plan to keep the heuristic-only mode.\n\n\u003e [!TIP]\n\u003e To avoid global npm permission issues, the installer now detects/installs [bun](https://bun.sh/) just like other dependencies and uses `bun install --global typescript` by default, falling back to npm only if bun isn’t available.\n\u003e\n\u003e The diagnostics also call out Swift guard readiness: if python3 is available we count `.swift` files under your repo and record whether the guard helper will actually run. That fact shows up in `install.sh --diagnose` output and the auto-generated session log so iOS/macOS teams can tell at a glance whether the ObjC-bridging heuristics are active.\n\n**Common combos**\n\n```bash\n# Preview everything without touching dotfiles or hooks\nbash install.sh --dry-run --no-path-modify --skip-hooks --non-interactive\n\n# CI-friendly install that self-tests the smoke harness\nbash install.sh --easy-mode --self-test --skip-hooks\n```\n\n### 🔄 **Auto-Update**\n\nThe `ubs` meta-runner supports an **opt-in** auto-update check (once every 24 hours). This is **disabled by default** for supply-chain safety.\n\nTo enable auto-update:\n```bash\nexport UBS_ENABLE_AUTO_UPDATE=1\n```\n\nTo disable it (even if enabled):\n```bash\nexport UBS_NO_AUTO_UPDATE=1\n# or\nubs --no-auto-update .\n```\n\nUltimate Bug Scanner is like having a senior developer review every line of code **in under 5 seconds**; it's the perfect automated companion to your favorite coding agent:\n\n```bash\n$ ubs .\n\n╔══════════════════════════════════════════════════════════════════════╗\n║  🔬 ULTIMATE BUG SCANNER v4.4 - Scanning your project...             ║\n╚══════════════════════════════════════════════════════════════════════╝\n\nProject:  /Users/you/awesome-app\nFiles:    247 JS/TS + 58 Python + 24 Go + 16 Java + 11 Ruby + 12 C++/Rust files\nFinished: 3.2 seconds\n\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\nSummary Statistics:\n  Files scanned:    247\n  🔥 Critical:      0    ← Would have crashed in production!\n  ⚠️  Warnings:      8    ← Should fix before shipping\n  ℹ️  Info:          23   ← Code quality improvements\n\n✨ EXCELLENT! No critical issues found ✨\n\n```\n\n---\n\n## ⚡ **Why Developers + AI Agents Will Love This Tool**\n\n### 🚀 **1. Catches What Humans \u0026 AI Miss**\n\n**18 specialized detection categories** covering the bugs that *actually* matter:\n\n\u003ctable\u003e\n\u003ctr\u003e\n\u003cth\u003eCategory\u003c/th\u003e\n\u003cth\u003eWhat It Prevents\u003c/th\u003e\n\u003cth\u003eTime Saved Per Bug\u003c/th\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eNull Safety\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003e\"Cannot read property of undefined\" crashes\u003c/td\u003e\n\u003ctd\u003e2-4 hours\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eSecurity Holes\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003eXSS, code injection, prototype pollution\u003c/td\u003e\n\u003ctd\u003e8-20 hours + reputation damage\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eAsync/Await Bugs\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003eRace conditions, unhandled rejections\u003c/td\u003e\n\u003ctd\u003e4-8 hours\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eMemory Leaks\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003eEvent listeners, timers, detached DOM\u003c/td\u003e\n\u003ctd\u003e6-12 hours\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eType Coercion\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003eJavaScript's === vs == madness\u003c/td\u003e\n\u003ctd\u003e1-3 hours\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd colspan=\"2\"\u003e\u003cstrong\u003e+ 13 more categories\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003e\u003cstrong\u003e100+ hours/month saved\u003c/strong\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n### 💨 **2. Blazing Fast (Because Your Time Matters)**\n\n```\nSmall project (5K lines):     0.8 seconds  ⚡\nMedium project (50K lines):   3.2 seconds  🚀\nLarge project (200K lines):  12 seconds    💨\nHuge project (1M lines):     58 seconds    🏃\n```\n\n**That's 10,000+ lines analyzed per second.** Faster than you can say \"but it worked on my machine.\"\n\n### 🤖 **3. Built FOR AI Agents, BY Developers Who Use AI**\n\nUnlike traditional linters that fight AI-generated code, this scanner **embraces** it:\n\n```markdown\n✅ Designed for Claude Code, Cursor, Windsurf, Aider, Continue, Copilot\n✅ Zero configuration - works with ANY JS/TS, Python, C/C++, Rust, Go, Java, or Ruby project\n✅ Integrates with git hooks, CI/CD, file watchers\n✅ Actionable output (tells you WHAT's wrong and HOW to fix it)\n✅ Fails fast in CI (catch bugs before they merge)\n✅ React Hooks dependency analysis that spots missing deps, unstable objects, and stale closures\n✅ Lightweight taint analysis that traces req.body/window.location/localStorage → innerHTML/res.send/eval/exec/db.query and flags flows without DOMPurify/escapeHtml/parameterized SQL\n```\n\n### 📊 **4. Real-World Impact**\n\n\u003ctable\u003e\n\u003ctr\u003e\n\u003cth\u003eScenario\u003c/th\u003e\n\u003cth\u003eWithout Scanner\u003c/th\u003e\n\u003cth\u003eWith Scanner\u003c/th\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eAI implements user auth\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003e\n  • 3 null pointer crashes (9h debugging)\u003cbr\u003e\n  • 1 XSS vulnerability (8h + incident)\u003cbr\u003e\n  • 2 race conditions (4h debugging)\u003cbr\u003e\n  \u003cstrong\u003eTotal: ~21 hours + security incident\u003c/strong\u003e\n\u003c/td\u003e\n\u003ctd\u003e\n  • All issues caught in 4 seconds\u003cbr\u003e\n  • Fixed before commit (15 min)\u003cbr\u003e\n  \u003cstrong\u003eTotal: 15 minutes\u003c/strong\u003e\u003cbr\u003e\n  \u003cstrong\u003eSavings: 84x faster\u003c/strong\u003e ⚡\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eRefactor payment flow\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003e\n  • Division by zero in edge case (3h)\u003cbr\u003e\n  • Unhandled promise rejection (2h)\u003cbr\u003e\n  • Missing error logging (1h)\u003cbr\u003e\n  \u003cstrong\u003eTotal: 6 hours debugging\u003c/strong\u003e\n\u003c/td\u003e\n\u003ctd\u003e\n  • Caught instantly (3 sec)\u003cbr\u003e\n  • Fixed before merge (10 min)\u003cbr\u003e\n  \u003cstrong\u003eTotal: 10 minutes\u003c/strong\u003e\u003cbr\u003e\n  \u003cstrong\u003eSavings: 36x faster\u003c/strong\u003e 🚀\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n---\n\n## 🤖 **AI Agent Integration (The Real Magic)**\n\n### On-Device Agent Guardrails\n\n`install.sh` now inspects your workstation for the most common coding agents (the same set listed below) and, when asked, drops guardrails that remind those agents to run `ubs --fail-on-warning .` before claiming a task is done. In `--easy-mode` this happens automatically; otherwise you can approve each integration individually.\n\n| Agent / IDE | What we wire up | Why it helps |\n|-------------|-----------------|--------------|\n| **Claude Code Desktop** (`.claude/hooks/on-file-write.sh`) | File-save hook that shells out to `ubs --ci` whenever Claude saves JS/TS files. | Keeps Claude from accepting “Apply Patch” without a fresh scan. |\n| **Cursor** (`.cursor/rules`) | Shared rule block that tells Cursor plans/tasks to run `ubs --fail-on-warning .` and summarize outstanding issues. | Cursor’s autonomous jobs inherit the same QA checklist as humans. |\n| **Codex CLI** (`.codex/rules/ubs.md`) | Adds the identical rule block for OpenAI's Codex terminal workflow. Supports both file and directory formats (v0.77.0+). | Ensures Codex sessions never skip the scanner during long refactors. |\n| **Gemini Code Assist** (`.gemini/rules`) | Guidance instructing Gemini agents to run `ubs` before closing a ticket. | Keeps Gemini’s asynchronous fixes aligned with UBS exit criteria. |\n| **Windsurf** (`.windsurf/rules`) | Guardrail text + sample command palette snippet referencing `ubs`. | Windsurf’s multi-step plans stay grounded in the same quality gate. |\n| **Cline** (`.cline/rules`) | Markdown instructions that Cline’s VS Code extension ingests. | Forces every “tool call” from Cline to mention scanner findings. |\n| **OpenCode MCP** (`.opencode/rules`) | Local MCP instructions so HTTP tooling always calls `ubs` before replying. | Makes OpenCode's multi-agent swarms share the same notion of \"done\". |\n\n#### Codex CLI v0.77.0+ Migration Note\n\nStarting with Codex CLI v0.77.0, the rules storage changed from a **single file** (`.codex/rules`) to a **directory** (`.codex/rules/`) containing individual rule files. The UBS installer handles both formats automatically:\n\n| Codex Version | Rules Location | UBS Installer Behavior |\n|---------------|----------------|------------------------|\n| \u003c v0.77.0 | `.codex/rules` (file) | Appends UBS quick reference to file |\n| ≥ v0.77.0 | `.codex/rules/` (directory) | Creates `.codex/rules/ubs.md` |\n\n**If you upgraded Codex and encounter issues**, migrate manually:\n\n```bash\n# Convert file to directory structure\nmv ~/.codex/rules ~/.codex/rules.backup\nmkdir ~/.codex/rules\nmv ~/.codex/rules.backup ~/.codex/rules/ubs.md\n```\n\nThe installer's `append_quick_reference_block()` function detects the storage format at runtime and writes to the appropriate location, so re-running `install.sh` after upgrading Codex will \"just work.\"\n\n### **Why This Matters for AI Workflows**\n\nWhen you're coding with AI, you're moving **10-100x faster** than traditional development. But bugs accumulate just as quickly. Traditional tools slow you down. This scanner keeps pace:\n\n```\nTraditional workflow:              AI-powered workflow with scanner:\n┌──────────────────┐              ┌──────────────────┐\n│ AI writes code   │              │ AI writes code   │\n└────────┬─────────┘              └────────┬─────────┘\n         │                                 │\n         ↓                                 ↓\n┌──────────────────┐              ┌──────────────────┐\n│ You review       │              │ Scanner runs     │\n│ (15 min)         │              │ (3 seconds)      │\n└────────┬─────────┘              └────────┬─────────┘\n         │                                 │\n         ↓                                 ↓\n┌──────────────────┐              ┌──────────────────┐\n│ Tests pass?      │              │ Critical bugs?   │\n└────────┬─────────┘              └────────┬─────────┘\n         │ NO!                              │ YES!\n         ↓                                 ↓\n┌──────────────────┐              ┌──────────────────┐\n│ Debug in prod    │              │ AI fixes them    │\n│ (6 hours)        │              │ (5 minutes)      │\n└──────────────────┘              └────────┬─────────┘\n                                           ↓\n                                  ┌──────────────────┐\n                                  │ Ship with         │\n                                  │ confidence        │\n                                  └──────────────────┘\n\nTotal: 6.25 hours                Total: 8 minutes\n```\n\n### **Pattern 1: Claude Code Integration (Real-Time Scanning)**\n\nDrop this into `.claude/hooks/on-file-write.sh`:\n\n```bash\n#!/bin/bash\n# Auto-scan UBS-supported languages (JS/TS, Python, C/C++, Rust, Go, Java, Ruby, Swift, C#, Elixir) on save\n\nif [[ \"$FILE_PATH\" =~ \\.(js|jsx|ts|tsx|mjs|cjs|py|pyw|pyi|c|cc|cpp|cxx|h|hh|hpp|hxx|rs|go|java|rb|cs|csx|ex|exs|eex|heex|leex|sface)$ ]]; then\n  echo \"🔬 Quality check running...\"\n\n  if ubs \"${PROJECT_DIR}\" --ci 2\u003e\u00261 | head -30; then\n    echo \"✅ No critical issues\"\n  else\n    echo \"⚠️  Issues detected - review above\"\n  fi\nfi\n```\n\n**Result:** Every time Claude writes code, the scanner catches bugs **instantly**.\n\n### **Pattern 2: Git Pre-Commit Hook (Quality Gate)**\n\nThe installer can set this up automatically, or add to `.git/hooks/pre-commit`:\n\n```bash\n#!/bin/bash\n# Block commits with critical bugs\n\necho \"🔬 Running bug scanner...\"\n\nif ! ubs . --fail-on-warning 2\u003e\u00261 | tee /tmp/scan.txt | tail -30; then\n  echo \"\"\n  echo \"❌ Critical issues found. Fix them or use: git commit --no-verify\"\n  echo \"\"\n  echo \"Top issues:\"\n  grep -A 3 \"🔥 CRITICAL\" /tmp/scan.txt | head -20\n  exit 1\nfi\n\necho \"✅ Quality check passed - committing...\"\n```\n\n**Result:** Bugs **cannot** be committed. Period.\n\n### **Pattern 3: Cursor/Windsurf/Continue Integration**\n\nAdd to your `.cursorrules` or similar:\n\n```markdown\n## Code Quality Standards\n\nBefore marking any task as complete:\n\n1. Run the bug scanner: `ubs .`\n2. Fix ALL critical issues (🔥)\n3. Review warnings (⚠️) and fix if trivial\n4. Only then mark task complete\n\nIf the scanner finds critical issues, your task is NOT done.\n```\n\n**Result:** AI agents have **built-in quality standards**.\n\n### **Pattern 4: CI/CD Pipeline (GitHub Actions Example)**\n\n```yaml\nname: Code Quality Gate\n\non: [push, pull_request]\n\njobs:\n  bug-scan:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v3\n\n      - name: Install Bug Scanner\n        run: |\n          curl -fsSL \"https://raw.githubusercontent.com/Dicklesworthstone/ultimate_bug_scanner/main/install.sh?$(date +%s)\" | bash -s -- --non-interactive\n\n      - name: Scan for Bugs\n        run: |\n          ubs . --fail-on-warning --ci\n```\n\n**Result:** Pull requests with critical bugs **cannot merge**.\n\n### **Pattern 5: The Fix-Verify Loop (For AI Agents)**\n\nThis is the golden pattern for AI coding workflows:\n\n```bash\n#!/bin/bash\n# Have your AI agent run this after implementing features\n\necho \"🔬 Post-implementation quality check...\"\n\n# Run scanner\nif ubs . --fail-on-warning \u003e /tmp/scan-result.txt 2\u003e\u00261; then\n  echo \"✅ All quality checks passed!\"\n  echo \"📝 Ready to commit\"\n  exit 0\nelse\n  echo \"❌ Issues found:\"\n  echo \"\"\n\n  # Show critical issues\n  grep -A 5 \"🔥 CRITICAL\" /tmp/scan-result.txt | head -30\n\n  echo \"\"\n  echo \"🤖 AI: Please fix these issues and re-run this check\"\n  exit 1\nfi\n```\n\n**Usage pattern:**\n\n```markdown\nUser: \"Add user registration with email validation\"\n\nAI Agent:\n1. Implements the feature\n2. Runs quality check (scanner finds 3 critical bugs)\n3. Fixes the bugs\n4. Re-runs quality check (passes)\n5. Commits the code\n\nTotal time: 12 minutes (vs. 6 hours debugging in production)\n```\n\n### **Pattern 6: The \"AI Agent Decision Tree\"**\n\nTrain your AI agent to use this decision tree:\n\n```\nDid I modify code in any supported language?\n(JS/TS, Python, Go, Rust, Java, C++, Ruby)\n         │\n         ↓ YES\nChanged more than 50 lines?\n         │\n         ↓ YES\n    Run scanner ←──────────┐\n         │                 │\n         ↓                 │\nCritical issues found? ────┤ YES\n         │ NO              │\n         ↓                 │\n     Warnings?             │\n         │                 │\n         ↓ YES             │\n  Show to user             │\n  Ask if should fix ───────┤\n         │ NO              │\n         ↓                 ↓\n    Commit code      Fix issues\n```\n\n---\n\n\u003e [!IMPORTANT]\n\u003e **Copy the blurb below to your project's `AGENTS.md`, `.claude/claude_docs/`, or `.cursorrules` file for comprehensive UBS integration guidance.**\n\n````markdown\n## UBS Quick Reference for AI Agents\n\nUBS stands for \"Ultimate Bug Scanner\": **The AI Coding Agent's Secret Weapon: Flagging Likely Bugs for Fixing Early On**\n\n**Install:** `curl -sSL https://raw.githubusercontent.com/Dicklesworthstone/ultimate_bug_scanner/main/install.sh | bash`\n\n**Golden Rule:** `ubs \u003cchanged-files\u003e` before every commit. Exit 0 = safe. Exit \u003e0 = fix \u0026 re-run.\n\n**Commands:**\n```bash\nubs file.ts file2.py                    # Specific files (\u003c 1s) — USE THIS\nubs $(git diff --name-only --cached)    # Staged files — before commit\nubs --only=js,python src/               # Language filter (3-5x faster)\nubs --ci --fail-on-warning .            # CI mode — before PR\nubs --help                              # Full command reference\nubs sessions --entries 1                # Tail the latest install session log\nubs .                                   # Whole project (ignores things like .venv and node_modules automatically)\n```\n\n**Output Format:**\n```\n⚠️  Category (N errors)\n    file.ts:42:5 – Issue description\n    💡 Suggested fix\nExit code: 1\n```\nParse: `file:line:col` → location | 💡 → how to fix | Exit 0/1 → pass/fail\n\n**Fix Workflow:**\n1. Read finding → category + fix suggestion\n2. Navigate `file:line:col` → view context\n3. Verify real issue (not false positive)\n4. Fix root cause (not symptom)\n5. Re-run `ubs \u003cfile\u003e` → exit 0\n6. Commit\n\n**Speed Critical:** Scope to changed files. `ubs src/file.ts` (\u003c 1s) vs `ubs .` (30s). Never full scan for small edits.\n\n**Bug Severity:**\n- **Critical** (always fix): Null safety, XSS/injection, async/await, memory leaks\n- **Important** (production): Type narrowing, division-by-zero, resource leaks\n- **Contextual** (judgment): TODO/FIXME, console logs\n\n**Anti-Patterns:**\n- ❌ Ignore findings → ✅ Investigate each\n- ❌ Full scan per edit → ✅ Scope to file\n- ❌ Fix symptom (`if (x) { x.y }`) → ✅ Root cause (`x?.y`)\n````\n\n---\n\n## 🎬 **See It In Action**\n\n*Examples show JavaScript output; each language has equivalent detections (Python: None checks, Go: nil guards, Rust: Option handling, etc.)*\n\n### **Example 1: Catching a Null Pointer Bug**\n\n```bash\n$ ubs src/\n\n▓▓▓ NULL SAFETY \u0026 DEFENSIVE PROGRAMMING\nDetects: Null pointer dereferences, missing guards, unsafe property access\n\n  🔥 CRITICAL (5 found)\n    Unguarded property access after getElementById\n    Consider: const el = document.getElementById('x'); if (!el) return;\n\n      src/components/form.js:42\n        const submitBtn = document.getElementById('submit-button');\n        submitBtn.classList.add('active');  // ← Crashes if element missing\n\n      src/utils/dom.js:87\n        const modal = document.querySelector('.modal');\n        modal.style.display = 'block';  // ← Runtime crash guaranteed\n\n  💡 Fix: Always check for null before accessing properties\n```\n\n**Before:** 3 production crashes this week\n**After:** 0 crashes, caught in 2 seconds\n\n### **Example 2: Security Vulnerability Detection**\n\n```bash\n▓▓▓ SECURITY VULNERABILITIES\nDetects: Code injection, XSS, prototype pollution, timing attacks\n\n  🔥 CRITICAL (3 found)\n    innerHTML without sanitization - XSS risk\n    Use textContent or DOMPurify.sanitize()\n\n      src/comments.js:156\n        element.innerHTML = userComment;  // ← XSS vulnerability!\n\n  🔥 CRITICAL (1 found)\n    Hardcoded API keys detected\n    Use environment variables or secret managers\n\n      src/config.js:23\n        const apiKey = \"sk_live_abc123xyz\";  // ← Security breach!\n```\n\n**Before:** Security incident, customer data at risk\n**After:** Vulnerability caught before git commit\n\n### **Example 3: Async/Await Gotchas**\n\n```bash\n▓▓▓ ASYNC/AWAIT \u0026 PROMISE PITFALLS\nDetects: Missing await, unhandled rejections, race conditions\n\n  🔥 CRITICAL (8 found)\n    await used in non-async function\n    SyntaxError in JavaScript\n\n      src/api/users.js:67\n        function saveUser(data) {\n          await database.insert(data);  // ← SyntaxError!\n        }\n\n  ⚠️  WARNING (12 found)\n    Promises without .catch() or try/catch\n    Unhandled rejections crash Node.js\n\n      src/services/email.js:45\n        sendEmail(user.email).then(result =\u003e ...)  // ← No error handling!\n```\n\n**Before:** Silent failures, mysterious bugs in production\n**After:** All async bugs caught and fixed before deploy\n\n---\n\n## 📋 **What It Detects (The Complete Arsenal)**\n\n*Each language module has specialized detections. Examples below are representative (JavaScript shown; Python has `eval()`, Go has goroutine leaks, Rust has `.unwrap()` panics, C++ has buffer overflows, etc.)*\n\n### 🔴 **Critical Issues (Production Blockers)**\n\nThese **WILL** cause crashes, security breaches, or data corruption:\n\n| Pattern | Example | Why It's Dangerous |\n|---------|---------|-------------------|\n| `eval()` usage | `eval(userInput)` | Allows arbitrary code execution - **RCE vulnerability** |\n| Direct NaN comparison | `if (x === NaN)` | Always returns false - **logic bug** |\n| Missing await | `asyncFunc()` in async context | Silent failures, race conditions - **data corruption** |\n| Prototype pollution | `obj.__proto__ = {}` | Security vulnerability - **privilege escalation** |\n| Unguarded null access | `el.style.color` without null check | **Runtime crash** guaranteed |\n| `parseInt` without radix | `parseInt(\"08\")` | Returns 0 in some browsers - **calculation bug** |\n| Empty catch blocks | `catch(e) {}` | Swallows errors - **debugging nightmare** |\n| `innerHTML` with user data | `el.innerHTML = userInput` | **XSS vulnerability** |\n| Missing async keyword | `await` without `async function` | **SyntaxError** |\n| Hardcoded secrets | `const key = \"sk_live...\"` | **Security breach** |\n\n### 🟡 **Warnings (Should Fix Before Shipping)**\n\nThese cause bugs, performance issues, or maintenance headaches:\n\n| Pattern | Example | Impact |\n|---------|---------|--------|\n| Promises without `.catch()` | `promise.then(...)` | Unhandled rejections crash Node.js |\n| Division without zero check | `total / count` | Returns `Infinity` or `NaN` |\n| Event listeners without cleanup | `addEventListener` in React | **Memory leak** (app gets slower over time) |\n| `setInterval` without clear | `setInterval(fn, 1000)` | **Timer leak** (infinite timers) |\n| `fetch()` without cancellation | `fetch(url)` | Stalled requests can hang workflows and exhaust resources |\n| `await` inside loops | `for(...) { await api.call() }` | **Slow** (sequential, not parallel) |\n| Array mutation during iteration | `arr.forEach(() =\u003e arr.push(...))` | **Skipped/duplicate** elements |\n| Missing switch default | `switch(x) { case 1: ... }` | Unhandled values cause silent failures |\n| `isNaN()` instead of `Number.isNaN()` | `isNaN(\"foo\")` | Type coercion bugs |\n\n### 🔵 **Info (Code Quality \u0026 Best Practices)**\n\nImprovements that make code cleaner and more maintainable:\n\n- Optional chaining opportunities (`obj?.prop?.value`)\n- Nullish coalescing opportunities (`value ?? default`)\n- TypeScript `any` usage (reduces type safety)\n- `console.log` statements (remove before production)\n- Technical debt markers (TODO, FIXME, HACK)\n- Performance optimizations (DOM queries in loops)\n- `var` usage (use `let`/`const` instead)\n- Deep property access without guards\n- Large inline arrays (move to separate files)\n- Complex nested ternaries (readability)\n\n---\n\n## ⚙️ **Advanced Configuration**\n\n### **Command-Line Options (Full Reference)**\n\n```bash\nubs [OPTIONS] [PROJECT_DIR] [OUTPUT_FILE]\n\nCore Options:\n  -v, --verbose            Show 10 code samples per finding (default: 3)\n  -q, --quiet              Minimal output (summary only)\n  --ci                     CI mode (stable output, no colors by default)\n  --fail-on-warning        Exit with code 1 on warnings (strict mode)\n  --version                Print UBS meta-runner version and exit\n  --profile=MODE           strict|loose (sets defaults for strictness)\n  --baseline=FILE          Compare findings against a baseline JSON (alias for --comparison)\n  -h, --help               Show help and exit\n\nGit Integration:\n  --staged                 Scan only files staged for commit\n  --diff, --git-diff       Scan only modified files (working tree vs HEAD)\n\nOutput Control:\n  --format=FMT             Output format: text|json|jsonl|sarif|toon (default: text)\n  --beads-jsonl=FILE      Write JSONL summary alongside normal output for Beads/\"strung\"\n  --no-color               Force disable ANSI colors\n  OUTPUT_FILE              Save report to file (auto-tees to stdout)\n\nFile Selection:\n  --include-ext=CSV        File extensions (default: auto-detect by language)\n                           JS: js,jsx,ts,tsx,mjs,cjs | Python: py,pyi,pyx\n                           Go: go | Rust: rs | Java: java | C++: cpp,cc,cxx,c,h\n                           Ruby: rb,rake,ru | C#: cs,csx | Custom: --include-ext=js,ts,vue\n  --exclude=GLOB[,...]     Additional paths to exclude (comma-separated)\n                           Example: --exclude=legacy (deps ignored by default)\n  --skip-size-check        Skip directory size guard (use with care)\n\nPerformance:\n  --jobs=N                 Parallel jobs for ripgrep (default: auto-detect cores)\n                           Set to 1 for deterministic output\n\nRule Control:\n  --skip=CSV               Skip categories by number (see output for numbers)\n                           Example: --skip=11,14  # Skip debug code + TODOs\n  --skip-type-narrowing    Disable helper-backed guard analysis (falls back to text heuristics)\n  --rules=DIR              Additional ast-grep rules directory\n                           Rules are merged with built-in rules\n  --no-auto-update         Disable automatic self-update\n  --suggest-ignore         Print large-directory candidates to add to .ubsignore (no changes applied)\n\nEnvironment Variables:\n  JOBS                     Same as --jobs=N\n  NO_COLOR                 Disable colors (respects standard)\n  CI                       Enable CI mode automatically\n  UBS_MAX_DIR_SIZE_MB      Max directory size in MB before refusing to scan (default: 1000)\n  UBS_SKIP_SIZE_CHECK      Skip directory size guard entirely (set to 1)\n\nArguments:\n  PROJECT_DIR              Directory to scan (default: current directory)\n  OUTPUT_FILE              Save full report to file\n\nExit Codes:\n  0                        No critical issues (or no issues at all)\n  1                        Critical issues found\n  1                        Warnings found (only with --fail-on-warning)\n  2                        Invalid arguments or environment error (e.g., missing ast-grep for JS/TS)\n```\n\n**Directory size guard**\n\nUBS computes scan size **after ignore filters** (defaults + `.ubsignore`) and prints:\n`Scan size after ignores: XMB (limit YMB)` before enforcing the limit. Override via\n`UBS_MAX_DIR_SIZE_MB` or `UBS_SKIP_SIZE_CHECK=1`, or pass `--skip-size-check`.\n\n### Environment errors (exit 2)\n\nIf UBS prints an **Environment error** and exits `2`, a required dependency is missing or unusable.\n\nMost common fix for JS/TS projects:\n\n```bash\nubs doctor --fix\n```\n\nOr install the dependency manually:\n\n```bash\nbrew install ast-grep            # or: cargo install ast-grep, npm i -g @ast-grep/cli\n```\n\nIf you’re intentionally scanning non-JS languages only, exclude JS:\n\n```bash\nubs --exclude=js .\n```\n\n### **Examples**\n\n```bash\n# Basic scan\nubs .\n\n# Verbose scan with full details\nubs -v /path/to/project\n\n# Strict mode for CI (fail on any warning)\nubs --fail-on-warning --ci\n\n# Save report without cluttering terminal\nubs . report.txt\n\n# Scan Vue.js project\nubs . --include-ext=js,ts,vue\n\n# Skip categories you don't care about\nubs . --skip=14  # Skip TODO/FIXME markers\n\n# Maximum performance (use all cores)\nubs --jobs=0 .  # Auto-detect\nubs --jobs=16 .  # Explicit core count\n\n# Exclude vendor code\nubs . --exclude=node_modules,vendor,dist,build\n\n# Large directories (size guard)\nUBS_MAX_DIR_SIZE_MB=5000 ubs .\nUBS_SKIP_SIZE_CHECK=1 ubs .\n\n# Custom rules directory\nubs . --rules=~/.config/ubs/custom-rules\n\n# Combine multiple options\nubs -v --fail-on-warning --exclude=legacy --include-ext=js,ts,tsx . report.txt\n```\n\n### JSONL schema\n\n`--format=jsonl` (and `--beads-jsonl=FILE`) emit newline-delimited objects for easy piping into tools like Beads or `jq`:\n\n```jsonl\n{\"type\":\"scanner\",\"project\":\"/path/to/project\",\"language\":\"python\",\"files\":42,\"critical\":1,\"warning\":3,\"info\":12,\"timestamp\":\"2025-11-22T09:04:20Z\"}\n{\"type\":\"totals\",\"project\":\"/path/to/project\",\"files\":99,\"critical\":1,\"warning\":3,\"info\":27,\"timestamp\":\"2025-11-22T09:04:22Z\"}\n```\n\n### **Custom AST-Grep Rules**\n\nYou can add your own bug detection patterns:\n\n```bash\n# Create custom rules directory\nmkdir -p ~/.config/ubs/rules\n\n# Add a custom rule (YAML format)\ncat \u003e ~/.config/ubs/rules/no-console-in-prod.yml \u003c\u003c'EOF'\nid: custom.no-console-in-prod\nlanguage: javascript\nrule:\n  any:\n    - pattern: console.log($$$)\n    - pattern: console.debug($$$)\n    - pattern: console.info($$$)\nseverity: warning\nmessage: \"console statements should be removed before production\"\nnote: \"Use a proper logging library or remove debug statements\"\nEOF\n\n# Run with custom rules\nubs . --rules=~/.config/ubs/rules\n```\n\n**Common custom rules:**\n\n```yaml\n# Enforce specific naming conventions\nid: custom.component-naming\nlanguage: typescript\nrule:\n  pattern: export function $NAME() { $$$ }\n  not:\n    pattern: export function $UPPER() { $$$ }\nseverity: info\nmessage: \"React components should start with uppercase letter\"\n```\n\n```yaml\n# Catch specific anti-patterns in your codebase\nid: custom.no-direct-state-mutation\nlanguage: typescript\nrule:\n  pattern: this.state.$FIELD = $VALUE\nseverity: critical\nmessage: \"Never mutate state directly - use setState()\"\n```\n\n### **Excluding False Positives**\n\nIf the scanner reports false positives for your specific use case:\n\n```bash\n# Skip entire categories\nubs . --skip=11,14  # Skip debug code detection and TODO markers\n\n# Exclude specific files/directories\nubs . --exclude=legacy,third-party,generated\n\n# For persistent config, create a wrapper script\ncat \u003e ~/bin/ubs-custom \u003c\u003c'EOF'\n#!/bin/bash\nubs \"$@\" \\\n  --exclude=legacy,generated \\\n  --skip=14 \\\n  --rules=~/.config/ubs/rules\nEOF\nchmod +x ~/bin/ubs-custom\n```\n\n---\n\n## 🎓 **How It Works (Under the Hood)**\n\n### **Multi-Layer Analysis Engine**\n\nThe scanner uses a sophisticated 4-layer approach:\n\n```\nLayer 1: PATTERN MATCHING (Fast) ──┐\n├─ Regex-based detection           │\n├─ Optimized with ripgrep          │\n└─ Finds 70% of bugs in \u003c1 second  │\n                                    ├──► Combined Results\nLayer 2: AST ANALYSIS (Deep) ──────┤\n├─ Semantic code understanding      │\n├─ Powered by ast-grep             │\n└─ Catches complex patterns        │\n                                    │\nLayer 3: CONTEXT AWARENESS (Smart) ┤\n├─ Understands surrounding code     │\n├─ Reduces false positives         │\n└─ Knows when rules don't apply    │\n                                    │\nLayer 4: STATISTICAL (Insightful)  │\n├─ Code smell detection            │\n├─ Anomaly identification          │\n└─ Architectural suggestions       │\n                                    ↓\n                         Final Report (3-5 sec)\n```\n\n### **Technology Stack**\n\n| Component | Technology | Purpose | Why This Choice |\n|-----------|-----------|---------|-----------------|\n| **Core Engine** | Bash 4.0+ | Orchestration | Universal compatibility, zero dependencies |\n| **Pattern Matching** | Ripgrep | Text search | 10-100x faster than grep, parallelized |\n| **AST Parser** | ast-grep | Semantic analysis | Understands code structure, not just text |\n| **Fallback** | GNU grep | Text search | Works on any Unix-like system |\n| **Rule Engine** | YAML | Pattern definitions | Human-readable, easy to extend |\n\n### **AST Rule Architecture: Ancestor-Aware Pattern Matching**\n\nUBS's ast-grep rules use a sophisticated technique called **ancestor traversal** to drastically reduce false positives. The key directive `stopBy: end` ensures patterns check the *entire* ancestor chain rather than just the immediate parent.\n\n**The Problem Without Ancestor Traversal:**\n\n```javascript\n// This code is SAFE - the fetch is properly handled:\nasync function safeFetch() {\n  try {\n    fetch('/api');  // Inside try block - exception will be caught\n  } catch (e) {\n    handleError(e);\n  }\n}\n\n// Naive AST rule checking only immediate parent:\n// ❌ False positive! Reports \"fetch without catch\" because\n//    fetch()'s immediate parent is the ExpressionStatement,\n//    not the try block.\n```\n\n**The Solution - Ancestor Traversal with `stopBy: end`:**\n\n```yaml\n# ast-grep rule with proper ancestor checking\nrule:\n  all:\n    - pattern: fetch($ARGS)\n    - not:\n        inside:\n          kind: try_statement\n          stopBy: end           # ← Key directive: traverse ALL ancestors\n    - not:\n        inside:\n          pattern: $_.catch($$)  # Check for .catch() in chain\n          stopBy: end\n```\n\nThe `stopBy: end` directive instructs ast-grep to walk up the *entire* ancestor tree until it finds a match (or reaches the root). Without it, only the immediate parent is checked—missing try blocks, function boundaries, and method chains.\n\n**Real-World Impact:**\n\n| Scenario | Without `stopBy: end` | With `stopBy: end` |\n|----------|----------------------|-------------------|\n| `try { fetch() } catch {}` | ❌ False positive | ✅ Correctly ignored |\n| `fetch().then().catch()` | ❌ False positive | ✅ Correctly ignored |\n| `return fetch()` | ❌ False positive | ✅ Correctly ignored |\n| `fetch()` standalone | ✅ Detected | ✅ Detected |\n\nThis technique is applied across 19+ rules in the JavaScript module alone, covering:\n- Promise chain detection (`.then()`, `.catch()`, `.finally()`)\n- Try-catch context awareness\n- Return statement handling\n- Async/await scope analysis\n\n### **Inline Suppression Comments**\n\nWhen a finding is intentional or a known false positive, suppress it inline:\n\n```javascript\n// Suppress a single line:\neval(trustedCode);  // ubs:ignore\n\n// Suppress with reason (recommended):\neval(adminScript);  // ubs:ignore -- admin-only trusted input\n```\n\n```python\n# Python suppression:\nexec(validated_code)  # ubs:ignore\n\n# Ruby suppression:\neval(safe_string)  # ubs:ignore\n```\n\n**Suppression Rules:**\n- Must appear on the **same line** as the flagged code\n- Works across all 10 supported languages\n- Suppresses all findings on that line (use sparingly)\n- Survives formatting tools that preserve trailing comments\n\n**Anti-patterns to avoid:**\n```javascript\n// ❌ Wrong - comment on previous line doesn't suppress:\n// ubs:ignore\neval(code);  // Still flagged!\n\n// ❌ Wrong - don't blanket-suppress large blocks:\n/* ubs:ignore */  // Doesn't work for block comments\n```\n\n### **Cross-Language Async Error Detection**\n\nUBS detects unhandled async errors consistently across all 10 languages. The patterns adapt to each language's idioms while providing equivalent coverage:\n\n| Language | Pattern | What UBS Detects |\n|----------|---------|------------------|\n| **JavaScript/TypeScript** | `promise.then()` without `.catch()`, `new Promise(async ...)`, `forEach(async ...)`, async array predicates, async timer/event/JSX-handler callbacks, `Promise.all(map(...))` without callback return | Dangling promises, missing `await`, unawaitable async callbacks, unhandled rejections |\n| **Python** | `asyncio.create_task()` without `await` | Orphaned tasks, missing `await`, unclosed coroutines |\n| **Go** | Goroutine without error channel | Fire-and-forget goroutines, leaked contexts |\n| **Rust** | `.unwrap()` / `.expect()` after partial guard | Panic after `if let Some`, missing `?` operator |\n| **Java** | `CompletableFuture` without `.exceptionally()` | Swallowed exceptions, missing `join()` |\n| **Ruby** | `Thread.new` without `.join` | Zombie threads, unhandled thread exceptions |\n| **C++** | `std::async` without `.get()` | Ignored futures, exception propagation |\n| **Swift** | `Task {}` without error handling | Unstructured concurrency leaks |\n| **C#** | `Task.Wait()` / `.Result` / `throw ex;` | Sync-over-async deadlocks, stack-trace loss, unsafe exception surfaces |\n\n**JavaScript Promise Chain Analysis:**\n\nThe scanner understands complex promise chains:\n\n```javascript\n// ✅ Handled - .catch() at end of chain:\nfetch('/api')\n  .then(r =\u003e r.json())\n  .then(data =\u003e process(data))\n  .catch(handleError);  // Scanner recognizes this catches all above\n\n// ✅ Handled - .catch() before .then():\nfetch('/api')\n  .catch(e =\u003e fallback)  // Early catch\n  .then(r =\u003e r.json());\n\n// ❌ Unhandled - .finally() doesn't catch:\nfetch('/api')\n  .then(r =\u003e r.json())\n  .finally(cleanup);  // Flagged: finally doesn't handle rejections\n\n// ❌ Unhandled - no error handling:\nasync function leaky() {\n  fetch('/api');  // Flagged: fire-and-forget promise\n}\n```\n\n### **Helper Script Verification**\n\nLanguage-specific helper scripts (Python AST walkers, Go analyzers, TypeScript type checkers) are verified with SHA-256 checksums before execution:\n\n```bash\n# Helper checksums embedded in each module:\nmodules/helpers/\n├── async_task_handles_csharp.py   # SHA-256 verified\n├── resource_lifecycle_csharp.py # SHA-256 verified\n├── resource_lifecycle_py.py    # SHA-256 verified\n├── resource_lifecycle_go.go    # SHA-256 verified\n├── resource_lifecycle_java.py  # SHA-256 verified\n├── type_narrowing_csharp.py    # SHA-256 verified\n├── type_narrowing_ts.js        # SHA-256 verified\n├── type_narrowing_rust.py      # SHA-256 verified\n├── type_narrowing_kotlin.py    # SHA-256 verified\n└── type_narrowing_swift.py     # SHA-256 verified\n```\n\nThe `ubs doctor` command validates all helper checksums:\n\n```bash\n$ ubs doctor\n🏥 UBS Environment Audit\n────────────────────────\n✓ helper checksum verified (resource_lifecycle_py.py)\n✓ helper checksum verified (type_narrowing_ts.js)\n...\n```\n\nIf a helper is modified or corrupted, the scanner fails safely with remediation guidance rather than executing unverified code.\n\n### **Unified Severity Normalization**\n\nAll 10 language modules normalize their findings to a consistent severity scale, ensuring predictable output regardless of source language:\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│  Language Tool Output      →   UBS Normalized Severity      │\n├─────────────────────────────────────────────────────────────┤\n│  ESLint \"error\"            →   critical                     │\n│  Pylint \"E\" / \"F\"          →   critical                     │\n│  Clippy \"deny\"             →   critical                     │\n│  Go vet \"error\"            →   critical                     │\n│  SpotBugs \"High\"           →   critical                     │\n│  RuboCop \"Fatal/Error\"     →   critical                     │\n├─────────────────────────────────────────────────────────────┤\n│  ESLint \"warn\"             →   warning                      │\n│  Pylint \"W\" / \"R\"          →   warning                      │\n│  Clippy \"warn\"             →   warning                      │\n│  Go vet \"warning\"          →   warning                      │\n│  SpotBugs \"Medium\"         →   warning                      │\n│  RuboCop \"Warning\"         →   warning                      │\n├─────────────────────────────────────────────────────────────┤\n│  ESLint \"suggestion\"       →   info                         │\n│  Pylint \"C\" / \"I\"          →   info                         │\n│  Clippy \"note\"             →   info                         │\n│  SpotBugs \"Low\"            →   info                         │\n│  RuboCop \"Convention\"      →   info                         │\n└─────────────────────────────────────────────────────────────┘\n```\n\n**Benefits of normalization:**\n- **Consistent exit codes**: Exit 1 always means \"critical issues found\" across all languages\n- **Unified JSON/SARIF output**: Downstream tools parse one schema, not 8 different formats\n- **Predictable `--fail-on-warning`**: Same behavior whether scanning Python, Rust, or TypeScript\n- **Cross-language metrics**: Compare code quality across polyglot projects fairly\n\nThe `normalize_severity()` function in each module handles edge cases like tool-specific severity strings, numeric levels, and legacy format variations.\n\n### **Performance Optimizations**\n\n```bash\n# Automatic parallelization (uses all CPU cores)\n- Auto-detects: 16-core = 16 parallel jobs\n- Manually set: --jobs=N\n\n# Smart file filtering (only scans relevant files)\n- JS/TS: .js, .jsx, .ts, .tsx, .mjs, .cjs (auto-skip node_modules/dist/build)\n- Python: .py + pyproject/requirements (skip venv/__pycache__)\n- C/C++: .c/.cc/.cpp/.cxx + headers + CMake files (skip build/out)\n- Rust: .rs + Cargo manifests (skip target/.cargo)\n- Go: .go + go.mod/go.sum/go.work (skip vendor/bin)\n- Java: .java + pom.xml + Gradle scripts (skip target/build/out)\n- Ruby: .rb + Gemfile/Gemspec/Rakefile (skip vendor/bundle,tmp)\n- Custom: --include-ext=js,ts,vue\n\n# Efficient streaming (low memory usage)\n- No temp files created\n- Results streamed as found\n- Memory usage: \u003c100MB for most projects\n\n# Incremental scanning (future feature)\n- Only scan changed files (git diff)\n- Cache previous results\n- 10x faster on large projects\n```\n\n---\n\n## 🏆 **Comparison with Other Tools**\n\n| Feature | Ultimate Bug Scanner | ESLint | TypeScript | SonarQube | DeepCode |\n|---------|---------------------|--------|------------|-----------|----------|\n| **Setup Time** | 30 seconds | 30 minutes | 1-2 hours | 2-4 hours | Account required |\n| **Speed (50K lines)** | 3 seconds | 15 seconds | 8 seconds | 2 minutes | Cloud upload |\n| **Zero Config** | ✅ Yes | ❌ No | ❌ No | ❌ No | ❌ No |\n| **Works Without Types** | ✅ Yes | ✅ Yes | ❌ No | ✅ Yes | ✅ Yes |\n| **Null Safety** | ✅ Yes | ⚠️ Limited | ✅ Yes | ⚠️ Limited | ⚠️ Limited |\n| **Security Scanning** | ✅ Yes | ⚠️ Plugin | ❌ No | ✅ Yes | ✅ Yes |\n| **Memory Leaks** | ✅ Yes | ❌ No | ❌ No | ⚠️ Limited | ❌ No |\n| **Async/Await** | ✅ Deep | ⚠️ Basic | ✅ Good | ⚠️ Basic | ⚠️ Basic |\n| **CI/CD Ready** | ✅ Yes | ✅ Yes | ✅ Yes | ✅ Yes | ⚠️ Cloud |\n| **Offline** | ✅ Yes | ✅ Yes | ✅ Yes | ⚠️ Limited | ❌ No |\n| **AI Agent Friendly** | ✅ Built for it | ⚠️ Config heavy | ⚠️ Config heavy | ❌ Complex | ⚠️ Cloud |\n| **Cost** | Free | Free | Free | $$$$ | $$$ |\n\n**When to use what:**\n\n- **Ultimate Bug Scanner**: Quick scans, AI workflows, no config needed\n- **ESLint**: Style enforcement, custom rules, team standards\n- **TypeScript**: Type safety (use WITH this scanner)\n- **SonarQube**: Enterprise compliance, detailed metrics\n- **DeepCode**: ML-powered analysis (if you trust cloud)\n\n**Best combo:** TypeScript + ESLint + Ultimate Bug Scanner = Maximum safety\n\n---\n\n## 🧠 **Project Justification and Rationale**\n\n### **Why This Exists (And Why It's Not \"Just Another Linter\")**\n\nYou might be thinking: *\"We already have ESLint, Pylint, Clippy, RuboCop... why build another tool?\"*\n\n**Fair question. And honestly, your first reaction is probably right to be skeptical.**\n\n### **The Initial Skepticism is Valid (But Misses the Point)**\n\nWhen you first look at UBS, it's natural to think:\n\n\u003e *\"This is just worse ESLint. It has fewer rules, uses regex (false positives!), and doesn't auto-fix anything. Why would I use this instead of mature, comprehensive linters?\"*\n\n**That's analyzing through the wrong lens.**\n\nYou're comparing it to tools designed for a **fundamentally different workflow** (human developers writing code manually) when it's solving a **fundamentally different problem** (LLM agents generating code at 100x speed).\n\nIt's like comparing a smoke detector to a building inspector:\n- **Building inspector (ESLint):** Thorough, comprehensive, finds every issue, takes hours\n- **Smoke detector (UBS):** Fast, catches critical dangers, instant alert, always running\n\n**You need both.** But when your house might be on fire (AI just generated 500 lines in 30 seconds), you want the smoke detector first.\n\n### **The Paradigm Shift: AI-Native Development**\n\nSoftware development is undergoing a **fundamental transformation**:\n\n**2020 (Pre-LLM Era):**\n- Developer writes 50-200 lines/day manually\n- Deep thought before each line\n- Single language per project (mostly)\n- Time to review: abundant\n- Quality gate: comprehensive linting + code review (hours)\n\n**2025 (LLM Era):**\n- AI generates 500-5000 lines/day across projects\n- Code appears in seconds\n- Polyglot projects standard (microservices in Go, UI in TypeScript, ML in Python, workers in Rust)\n- Time to review: scarce\n- Quality gate needed: instant feedback (\u003c5s) or the loop breaks\n\n**Traditional tools weren't designed for this.** They were built when \"code generation\" meant 200 lines/day, not 2000.\n\n### **Here's the Fundamental Difference:**\n\n### **1. This Tool is Built FOR AI Agents, Not Just Humans**\n\nTraditional linters were designed for **human developers** in **single-language codebases**. UBS is designed for **LLM coding agents** working across **polyglot projects**.\n\n**The paradigm shift:**\n\n| Traditional Linting (Human-First) | UBS Approach (LLM-First) |\n|---|---|\n| **Goal:** Comprehensive coverage + auto-fix\u003cbr\u003e**Speed:** 15-60 seconds acceptable\u003cbr\u003e**Setup:** 30 min config per language\u003cbr\u003e**Languages:** One tool per language\u003cbr\u003e**False positives:** Must be \u003c1% (frustrates humans)\u003cbr\u003e**Output:** Human-readable prose | **Goal:** Critical bug detection + fast feedback\u003cbr\u003e**Speed:** \u003c5 seconds required\u003cbr\u003e**Setup:** Zero config (instant start)\u003cbr\u003e**Languages:** One scan for all 10 languages\u003cbr\u003e**False positives:** 10-20% OK (LLMs filter instantly)\u003cbr\u003e**Output:** Structured file:line for LLM parsing |\n\n### **2. LLMs Don't Need Auto-Fix—They ARE the Auto-Fix Engine**\n\n**Why traditional linters have auto-fix:**\n```javascript\n// ESLint flags: \"Use === instead of ==\"\nif (value == null)  // ❌\n\n// ESLint auto-fix (rigid, no context):\nif (value === null)  // ✅ Technically correct, but...\n```\n\n**Why UBS doesn't (and shouldn't):**\n```javascript\n// UBS flags: \"Type coercion bug: == should be ===\"\nif (value == null)  // ❌\n\n// Claude reads the error and understands context:\nif (value !== null \u0026\u0026 value !== undefined)  // ✅ Better - handles both\n// OR\nif (value != null)  // ✅ Or keeps == for null/undefined (intentional)\n```\n\n**The hard part is DETECTION, not fixing.** Once flagged, LLMs can:\n- Understand semantic context\n- Consider surrounding code\n- Apply the right fix (not just the mechanical one)\n- Refactor holistically\n\nAuto-fix would be **worse** because it's context-free. LLMs need to know **WHAT'S wrong** and **WHERE**, then they fix it properly.\n\n### **3. The Multi-Language Zero-Config Design is the Moat**\n\n**Imagine asking Claude to set up quality gates for a polyglot project:**\n\n**Traditional approach (15-30 min per project):**\n```bash\n# JavaScript/TypeScript\nnpm install --save-dev eslint @eslint/js @typescript-eslint/parser\n# Create .eslintrc.js (200 lines of config)\n\n# Python\npip install pylint black mypy\n# Create .pylintrc, pyproject.toml sections\n\n# Rust\n# Add to Cargo.toml: [lints]\n# Configure clippy rules\n\n# Go\n# Install golangci-lint, create .golangci.yml\n\n# Java\n# Setup Checkstyle + PMD + SpotBugs + config XMLs\n\n# C++\n# Setup clang-tidy, create .clang-tidy config\n\n# Ruby\n# Create .rubocop.yml with 150+ lines\n\n# Now run 7 different commands and parse 7 different output formats...\n```\n\n**UBS approach (30 seconds):**\n```bash\ncurl -fsSL https://raw.githubusercontent.com/.../install.sh | bash\nubs .\n\n# Done. All 10 languages scanned, unified report.\n```\n\n**This matters because:**\n- LLMs generate code across languages in one session (Python API → Go service → TypeScript UI → Rust worker)\n- Configuring 7 tools is error-prone for LLMs\n- Humans don't want to maintain 7 different config files\n- CI/CD pipelines want one command, one exit code\n\n### **Type Narrowing Coverage Across Languages**\n\n- **TypeScript** – UBS shells out to `tsserver` (via the bundled helper) whenever Node.js + the `typescript` package are available. The installer surfaces a \"Type narrowing readiness\" diagnostic so you immediately know if tsserver-powered guards are running. Category 7 also flags bearer tokens, webhook signatures, CSRF values, API keys, HMAC digests, and password-reset secrets compared with `==`, `===`, `!=`, or `!==` instead of timing-safe equality, catches request-derived object merges and dynamic key writes that can allow prototype pollution unless prototype keys are rejected, catches request-derived SQL string construction flowing into raw `db.query`/`sequelize.query`/Prisma `$queryRawUnsafe` execution instead of parameterized calls, catches server-side proxy and rewrite targets from `createProxyMiddleware`, `http-proxy`, `proxy.web`/`proxy.ws`, and `NextResponse.rewrite` when they are request-derived without proxy target validation, and catches JWT decode-only flows, explicit verification bypass options, `none` algorithms, and verifier calls that lack issuer/audience claim binding.\n- **Rust** – A Python helper inspects `if let Some/Ok` guard clauses and flags subsequent `.unwrap()`/`.expect()` calls outside of exiting blocks. The Rust security pass also catches bearer tokens, webhook signatures, HMAC/MAC digests, CSRF values, API keys, and password-reset secrets compared with `==` or `!=` instead of `subtle::ConstantTimeEq`, `ring::constant_time::verify_slices_are_equal`, `crypto_memcmp`, or a reviewed constant-time helper; JWT decode/validation bypasses such as `dangerous::insecure_decode`, `dangerous_unsafe_decode`, `insecure_disable_signature_validation()`, `validate_exp = false`, `validate_aud = false`, and `decode` calls whose validation does not bind and require both issuer and audience; archive member paths flowing into extraction destinations without `enclosed_name()`/`unpack_in()`-style containment; predictable temp-file writes that use shared temp paths without `tempfile` or `create_new(true)`; request-derived redirect targets flowing into redirects or `Location` headers without local-path or redirect host allow-list validation; request-derived values interpolated into SQL strings that reach raw sqlx/diesel/rusqlite/postgres execution sinks instead of parameterized placeholders; credentialed wildcard or reflected-origin CORS policies without an explicit trusted-origin allow-list; and request/header values flowing into non-`Location` response headers without CR/LF rejection, `HeaderValue::from_str`, encoding, or a header-safe helper. Fixtures and manifest cases keep these regressions tested.\n- **Go** – Category 9 now flags bearer tokens, webhook signatures, HMAC/MAC digests, CSRF values, API keys, and password-reset secrets compared with `==` or `!=` instead of `hmac.Equal`, `subtle.ConstantTimeCompare`, or a reviewed constant-time helper. It also catches JWT verification bypasses such as `ParseUnverified`, `SigningMethodNone`, `WithoutClaimsValidation`, `jwt.Parse` / `ParseWithClaims` callbacks that trust claims without signing-method validation, verified JWTs that omit issuer/audience claim binding, request-derived reverse proxy targets flowing into `httputil.NewSingleHostReverseProxy`, `ProxyRequest.SetURL`, or `Director` URL mutation without HTTPS plus host allow-list validation, and request/form/header values interpolated into SQL execution or query-builder strings instead of passed as parameters.\n- **Kotlin** – The Java-family module scans `.kt`/`.kts` sources for `if (value == null)` guards that merely log and keep running before hitting `value!!`, and its security pass now catches request/Ktor params, request paths, and upload filenames flowing into file read/write/serve/delete sinks, request-derived values flowing into response headers without CR/LF safety, request-derived query/header URLs flowing into Ktor-style HTTP client calls, zip extraction that writes `entry.name` / `entry.path` into destination paths without containment checks, and security-sensitive tokens, CSRF nonces, API keys, OTPs, reset codes, and invite codes built from `kotlin.random.Random`, `java.util.Random`, `ThreadLocalRandom`, `UUID.randomUUID`, or predictable time material instead of `SecureRandom`.\n- **Swift** – The dedicated `ubs-swift` module now ships the guard-`let` helper directly, so optional chaining/Objective‑C bridging heuristics fire even when you run `ubs --only=swift` locally (no piggybacking on the Java module). It catches cases where code logs and keeps going before force-unwrapping `value!`, protecting iOS/macOS pipelines that blend Swift + ObjC. The Swift security pass also tracks request query, route, URL path, and upload filename values into file read/write/serve/delete sinks unless they are reduced to a basename or pass a standardized root-containment check, flags request-derived redirect targets that reach redirects or `Location` headers without local-url or host allow-list validation, flags request/header/cookie/content values reaching non-`Location` response headers without CR/LF stripping/rejection, encoding, or a header-safe helper, flags request-derived outbound URLs that reach URLSession, URLRequest handoffs, blocking URL reads, or HTTP clients without https scheme and host allow-list validation, and now flags security-sensitive tokens, CSRF nonces, API keys, OTPs, salts, and reset/invite codes built from non-cryptographic Swift randomness or predictable time/process material instead of `SecRandomCopyBytes` or CryptoKit-backed helpers.\n\n### **Resource Lifecycle AST Coverage**\n\n- **Python** – `modules/helpers/resource_lifecycle_py.py` now reasons over the AST, tracking `with`/`async with`, alias imports, and `.open()`/`.connect()` calls so `ubs-python` warns only when a handle is truly leaking. Pathlib `Path.open()` and similar patterns are handled without brittle regexes.\n- **Java** – New ast-grep rules (`java.resource.executor-no-shutdown`, `java.resource.thread-no-join`, `java.resource.jdbc-no-close`, `java.resource.resultset-no-close`, `java.resource.statement-no-close`) ensure ExecutorServices, raw `Thread`s, `java.sql.Connection`s, `Statement`/`PreparedStatement`/`CallableStatement`, and `ResultSet` handles all get proper shutdown/close semantics before the regex fallback ever runs.\n- **C#** – `modules/helpers/resource_lifecycle_csharp.py`, `modules/helpers/type_narrowing_csharp.py`, and `modules/helpers/async_task_handles_csharp.py` now catch disposable-handle leaks (`CancellationTokenSource`, stream-like readers/writers, `HttpRequestMessage`), null/`TryGetValue` guards that log but still fall through into dereferences, and `Task.Run`/`Task.Factory.StartNew` handles that are created but never observed. The C# security pass also tracks ASP.NET request/query/header/path values and upload filenames into file read/write/serve/delete sinks unless they go through `Path.GetFileName` or `Path.GetFullPath` containment checks, flags request/header/cookie/route values that reach `Redirect`, `Response.Redirect`, `RedirectResult`, or `Location` headers without local-url or host allow-list validation, flags request/query/header/form and annotated action values reaching response headers without CR/LF stripping, rejection, or encoding, and flags request/header-derived outbound URLs reaching `HttpClient`, `HttpRequestMessage`, `WebRequest`, `WebClient`, or REST-style clients without URI parsing plus scheme and host allow-list validation.\n- **C++ / Rust / Ruby / Elixir** – These modules already relied on ast-grep rule packs or language-tailored context passes; the “Universal AST Adoption” epic is now complete with every language module (JS, Python, Go, C++, Rust, Java, Ruby, Swift, C#, Elixir) running semantic detectors instead of fragile grep-only heuristics. C++ now tracks CGI/query/header URL values into redirect functions and `Location` headers unless they pass through same-origin local-path checks or explicit redirect host allow-lists, into non-`Location` response headers unless they reject/strip CR/LF, encode header fragments, or pass through a header-safe helper, into libcurl/common HTTP client URL sinks unless they pass through a safe outbound URL helper, and flags security-sensitive tokens, CSRF nonces, API keys, OTPs, salts, reset codes, and invite codes built from `rand`, `random`, implementation-defined `random_device`, Mersenne Twister-style engines, timestamps, hashes, or process IDs instead of OS/crypto-backed random bytes. Rust tracks query/header/env/CLI URL values into `reqwest`, `ureq`, `surf`, `isahc`, and request-builder sinks unless they pass through a safe outbound URL helper or equivalent URL parsing plus host allow-list validation, tracks query/header/host redirect targets into redirect responses or `Location` headers unless they pass through same-origin local-path checks or redirect host allow-lists, tracks request/header values into non-`Location` response headers unless they reject/strip CR/LF, use `HeaderValue` validation, encode header fragments, or pass through a header-safe helper, and tracks request-derived values interpolated into raw SQL strings that reach sqlx, diesel, rusqlite, postgres, or generic query execution sinks without parameter binding. Ruby's security pass now tracks Rack/Rails params and upload filenames into file read/write/serve/delete sinks unless the path is reduced to `File.basename` or guarded by `File.expand_path` containment checks, flags request-derived redirect targets reaching `redirect_to`, Sinatra/Rack `redirect`, or `Location` headers without local-url or host allow-list validation, flags request/header/cookie/env values reaching non-`Location` response headers without CR/LF stripping, rejection, encoding, or a header-safe helper, and flags request-derived outbound URLs reaching common Ruby HTTP clients without URI parsing plus scheme and host allow-list validation. Elixir's security pass tracks Plug/Phoenix params, request paths, and upload filenames into `File.*`, `send_file`, and `send_download` sinks unless the path is reduced to `Path.basename` or guarded by `Path.expand` containment checks, flags request-derived redirect targets reaching Phoenix/Plug redirects or `Location` headers without local-url or host allow-list validation, flags request/header/cookie values reaching non-`Location` response headers without CR/LF stripping, rejection, encoding, or a header-safe helper, flags request-derived outbound URLs reaching Req, HTTPoison, Finch, Tesla, hackney, Mint, or `:httpc` without URI parsing plus scheme and host allow-list validation, and flags Phoenix/Guardian/Joken hardcoded config secrets such as `secret_key_base`, signing salts, JWT/API secrets, and literal `System.get_env/2` fallbacks.\n\n#### Python – AST helper in action\n\n```python\nimport asyncio, subprocess\n\nfh = open(\"/tmp/leaky.txt\", \"w\")\nproc = subprocess.Popen([\"sleep\", \"1\"])\n\nasync def leak_task():\n    task = asyncio.create_task(asyncio.sleep(1))\n    await asyncio.sleep(0.1)\n    return task\n\nasyncio.run(leak_task())\n```\n\n```\n$ ./ubs --only=python test-suite/python/buggy/resource_lifecycle.py\n  🔥 File handles opened without context manager/close [resource_lifecycle.py:4]\n    File handle fh opened without context manager or close()\n  ⚠ Popen handles not waited or terminated [resource_lifecycle.py:7]\n```\n\nThe helper catches the unguarded file handle, zombie subprocess, and orphaned asyncio task because it walks the AST (tracking aliases and async contexts) instead of grepping for strings.\n\n#### Go – AST helper validating cleanups\n\n```go\nctx, cancel := context.WithTimeout(context.Background(), time.Second)\nticker := time.NewTicker(time.Millisecond * 500)\ntimer := time.NewTimer(time.Second)\nf, _ := os.Open(\"/tmp/data.txt\")\n\n_ = ctx\n_ = cancel\n_ = ticker\n_ = timer\n_ = f\n```\n\n```\n$ ./ubs --only=golang test-suite/golang/buggy/resource_lifecycle.go\n  🔥 context.With* without deferred cancel [resource_lifecycle.go:10]\n  ⚠ time.NewTicker not stopped [resource_lifecycle.go:13]\n  ⚠ time.NewTimer not stopped [resource_lifecycle.go:15]\n  ⚠ os.Open/OpenFile without defer Close() [resource_lifecycle.go:17]\n```\n\nBecause the helper hashes AST positions, the manifest can assert on deterministic substrings (context/ticker/timer/file) and we avoid flakiness from color codes or log headings.\n\nUse `--skip-type-narrowing` (or `UBS_SKIP_TYPE_NARROWING=1`) when you want to bypass all of these guard analyzers—for example on air-gapped CI environments or when validating legacy projects one language at a time.\n\n### **4. Speed Enables Tight Iteration Loops**\n\nThe **generate → scan → fix** cycle needs to be **fast** for AI workflows:\n\n```\n┌─────────────────────────────────────────┐\n│  Traditional Linter (30-45 seconds)     │\n├─────────────────────────────────────────┤\n│  Claude generates code:        10s      │\n│  Run ESLint + Pylint + ...     30s  ⏳  │\n│  Claude reads findings:         5s      │\n│  Claude fixes bugs:            15s      │\n│  Re-run linters:               30s  ⏳  │\n│  ──────────────────────────────────     │\n│  Total iteration:              90s      │\n└─────────────────────────────────────────┘\n\n┌─────────────────────────────────────────┐\n│  UBS (3-5 seconds)                      │\n├─────────────────────────────────────────┤\n│  Claude generates code:        10s      │\n│  Run UBS:                       3s  ⚡  │\n│  Claude reads findings:         2s      │\n│  Claude fixes bugs:            10s      │\n│  Re-run UBS:                    3s  ⚡  │\n│  ──────────────────────────────────     │\n│  Total iteration:              28s      │\n└─────────────────────────────────────────┘\n\n3x faster feedback loop = 3x more iterations in the same time\n```\n\n**When you're shipping 10+ features a day with AI assistance, this compounds.**\n\n### **5. Detecting LLM-Specific Bug Patterns**\n\nUBS targets the bugs **AI agents actually generate**, not every possible code smell.\n\n**Bugs LLMs frequently produce:**\n\n| Pattern | Why LLMs Generate It | Traditional Linters |\n|---------|---------------------|---------------------|\n| Missing `await` | Forgets `async` keyword, syntax looks fine | ❌ TypeScript only |\n| Unguarded null access | \"Optimistic\" coding - assumes happy path | ⚠️ Requires strict config |\n| `eval()` / code injection | Reaches for \"easy\" dynamic solution | ✅ Most flag this |\n| Memory leaks (event listeners) | Doesn't think about cleanup lifecycle | ❌ ESLint plugin needed |\n| `innerHTML` XSS | Doesn't threat-model user input | ⚠️ Security plugins only |\n| Division by zero | Doesn't consider edge cases | ❌ Most miss this |\n| Hardcoded secrets | Uses placeholder, forgets to externalize | ⚠️ Requires secrets scanner |\n| Goroutine leaks | Forgets context cancellation | ❌ Go-specific tooling |\n| `.unwrap()` panics | Assumes success path | ✅ Clippy catches |\n| Buffer overflows | Forgets bounds checking | ⚠️ Sanitizers only |\n\n**UBS is optimized for this specific threat model.**\n\n### **6. Novel Analysis: Deep Property Guard Correlation**\n\nThis is genuinely **not available in standard linters**:\n\n```python\n# Code LLM generates:\ndef get_theme(user):\n    return user.profile.settings.theme  # ❌ Unguarded chain\n\n# ESLint/Pylint: ✅ No error (syntactically correct)\n# TypeScript: ✅ No error (if types claim non-null)\n\n# UBS Deep Guard Analysis:\n# 1. Scans for: user.profile.settings.theme (found at line 42)\n# 2. Scans for: if user and user.profile and user.profile.settings\n# 3. Correlates: NO MATCHING GUARD FOUND\n# 4. Reports: ⚠️ Unguarded deep property access\n```\n\n**This requires:**\n- AST extraction of property chains across the file\n- AST extraction of conditional guards\n- Cross-reference matching with context awareness\n- Contextual suggestions\n\n**Nobody else does this by default** because it's not a lint rule—it's a **correlation analysis** across multiple code patterns.\n\n### **7. Complementary, Not Competitive**\n\n**UBS is designed to work WITH existing tools, not replace them:**\n\n```\n┌────────────────────────────────────────────────────┐\n│  Your Quality Stack (Recommended)                  │\n├────────────────────────────────────────────────────┤\n│  TypeScript           → Type safety                │\n│  ESLint/Clippy/etc    → Comprehensive linting      │\n│  Jest/PyTest          → Unit tests                 │\n│  ✨ UBS                → AI-generated bug oracle   │\n│  GitHub Actions       → CI/CD integration          │\n└────────────────────────────────────────────────────┘\n```\n\n**Use UBS for:**\n- ✅ Fast multi-language scanning in AI workflows\n- ✅ Critical bug detection before commits\n- ✅ Git hooks that block obviously broken code\n- ✅ Claude/Cursor/AI agent quality guardrails\n- ✅ Polyglot projects where configuring 7 linters is painful\n\n**Use ESLint/Pylint/Clippy/etc for:**\n- ✅ Comprehensive style enforcement\n- ✅ Framework-specific rules (React hooks, etc.)\n- ✅ Custom team conventions\n- ✅ Auto-formatting\n- ✅ Deep single-language analysis\n\n**They solve different problems.** UBS is the \"smoke detector\" (fast, catches critical issues). Traditional linters are the \"building inspector\" (thorough, catches everything).\n\n### **8. The Technical Moat**\n\nWhat makes this hard to replicate:\n\n**Multi-layer analysis:**\n```\nLayer 1: Ripgrep (regex)     → 70% of bugs in 0.5s\nLayer 2: ast-grep (AST)      → Complex semantic patterns\nLayer 3: Correlation logic   → Cross-pattern analysis (novel)\nLayer 4: Metrics collection  → Time-series quality tracking\n```\n\n**This combination of speed + semantic understanding + correlation is unique.**\n\n**Unified multi-language runner:**\n- Auto-detects 10 languages in one scan\n- Parallel execution (Go + Python + Rust simultaneously)\n- Unified JSON/SARIF output for tooling\n- Module system with lazy download/caching\n\n**LLM-optimized integration points:**\n- Git hooks (block bad commits)\n- Claude Code file-write hooks\n- `.cursorrules` / `.aiconfig` integration\n- Clean structured output for LLM parsing\n\n### **9. 30 Rules is Better Than 600 (For This Use Case)**\n\n**You might notice:** ESLint has 200+ core rules, Clippy has 600+ lints, but UBS has ~30 patterns per language.\n\n**That's intentional, not a limitation.**\n\n**The 80/20 rule for AI-generated bugs:**\n- **80% of production-breaking bugs** come from ~30 common patterns\n- **20% of edge cases** require the other 570 rules\n\n**For LLM workflows, you want:**\n```\n✅ Fast scan (3s) that catches 80% of critical bugs\n   ↓\n   LLM fixes them immediately\n   ↓\n   ✅ Fast re-scan (3s) confirms fixes\n   ↓\n   Then run comprehensive linters (30s) for the remaining 20%\n```\n\n**Not:**\n```\n❌ Comprehensive scan (30s) that catches 100% of issues\n   ↓\n   LLM waits... workflow broken... context switch...\n   ↓\n   Slower iteration = fewer features shipped\n```\n\n**The bugs UBS targets are:**\n- Missing `await` (crashes)\n- Null pointer access (crashes)\n- Security holes: `eval()`, XSS, hardcoded secrets (breaches)\n- Memory leaks (performance degradation)\n- Race conditions (data corruption)\n\n**The bugs comprehensive linters add:**\n- Inconsistent quote style (style)\n- Missing trailing commas (style)\n- Prefer `const` over `let` when not reassigned (style)\n- Function name should be camelCase (style)\n- Line too long (style)\n\n**Which matters more when AI just generated 500 lines that might have `eval()` and missing `await` everywhere?**\n\nTarget the **critical bugs** that cost hours. Let comprehensive linters handle style in a separate pass.\n\n### **10. Market Timing: This Wouldn't Have Made Sense 3 Years Ago**\n\n**Why this tool exists NOW:**\n\n**2021:**\n- GitHub Copilot launches (single-line completions)\n- Still mostly human-written code\n- Traditional linting workflow works fine\n\n**2023:**\n- ChatGPT/GPT-4 can generate full functions\n- Claude Code, Cursor emerge\n- Devs start AI-assisted workflows\n- Pain point appears: \"AI is fast but buggy\"\n\n**2025:**\n- LLMs generate entire features in minutes\n- Multi-file refactors happen in seconds\n- Polyglot microservices are standard\n- **Quality gates can't keep up with generation speed**\n\n**The problem UBS solves didn't exist before LLM coding became mainstream.**\n\nThis tool is **perfectly timed** for the AI coding explosion happening RIGHT NOW.\n\n### **11. False Positive Philosophy**\n\n**For human developers:**\n- False positive = context switch + investigation + frustration\n- Acceptable rate: \u003c1%\n\n**For LLM agents:**\n- False positive = parse (0.1s) + analyze (0.5s) + determine safe (0.2s)\n- Acceptable rate: 10-20%\n\n**LLMs don't get frustrated.** They evaluate every finding programmatically.\n\n**This means UBS can be more aggressive:**\n- Flag suspicious patterns even if not 100% certain\n- Catch more bugs at the cost of some noise\n- LLMs filter false positives cognitively (for free)\n\nBetter to flag 100 issues where 20 are safe than miss 1 critical bug.\n\n---\n\n## **FAQ: Common Questions and Objections**\n\n### **Q: \"Isn't this just reinventing the wheel? ESLint already exists.\"**\n\n**A:** It's not reinventing the wheel—it's building a different vehicle for a different road.\n\nESLint is a **truck** (heavy, comprehensive, hauls everything).\nUBS is a **sports car** (fast, targeted, gets you there quickly).\n\nYou wouldn't use a truck for a Formula 1 race. You wouldn't use a sports car to move furniture.\n\n**Different tools, different use cases.** Use UBS for rapid AI iteration, ESLint for comprehensive quality enforcement.\n\n---\n\n### **Q: \"Why not just contribute these patterns to existing linters?\"**\n\n**A:** Three reasons:\n\n**1. Different design philosophy**\n- Existing linters: comprehensive, human-first, single-language\n- UBS: fast, LLM-first, multi-language, correlation-based\n\nThese are fundamentally incompatible goals. ESLint would never accept \"10-20% false positives are fine\" or \"skip auto-fix entirely.\"\n\n**2. Multi-language meta-runner**\n- The unified runner that auto-detects 10 languages is the core innovation\n- This doesn't fit into any single linter's architecture\n- Each linter project has different maintainers, philosophies, release cycles\n\n**3. Correlation analysis is novel**\n- Deep property guard matching isn't a \"lint rule\"\n- It's cross-pattern analysis that requires a different architecture\n- Existing linters don't have this capability baked into their core\n\nContributing patterns misses the point—**the integration IS the innovation.**\n\n---\n\n### **Q: \"What about Semgrep? Doesn't it do multi-language pattern matching?\"**\n\n**A:** Semgrep is excellent and closer to UBS than traditional linters. Key differences:\n\n| Feature | Semgrep | UBS |\n|---------|---------|-----|\n| **Setup** | Requires config file + rule selection | Zero config |\n| **Speed** | ~10-20s on medium projects | ~3s (optimized for speed) |\n| **Target user** | Security teams, human developers | LLM agents |\n| **Rule focus** | Security + custom patterns | AI-generated bug patterns |\n| **Multi-language** | ✅ Yes | ✅ Yes |\n| **Correlation analysis** | ❌ Pattern matching only | ✅ Deep guards, metrics |\n| **LLM integration** | Not designed for it | Purpose-built |\n\n**Use Semgrep if:** You need custom security rules and have time to configure them.\n**Use UBS if:** You want instant AI workflow integration with zero setup.\n\n**They're complementary.** Some users run both.\n\n---\n\n### **Q: \"Won't regex-based detection have tons of false positives?\"**\n\n**A:** Less than you'd think, and it's acceptable for LLM consumers.\n\n**Reality check:**\n- **Layer 1 (ripgrep/regex):** ~15-20% false positive rate on some patterns\n- **Layer 2 (ast-grep/AST):** ~2-5% false positive rate (semantic understanding)\n- **Layer 3 (correlation):** ~1-3% false positive rate (contextual analysis)\n\n**Blended approach:** ~8-12% overall false positive rate.\n\n**Why this is OK:**\n- LLMs don't get frustrated like humans do\n- They evaluate findings in 0.8 seconds total\n- Better to flag 100 (20 safe) than miss 1 critical bug\n- Humans reviewing AI code ALREADY have to check everything anyway\n\n**For critical patterns** (eval, XSS, hardcoded secrets), we use ast-grep (high precision).\n**For style patterns**, we use regex (fast, some FP acceptable).\n\n**And we're always improving.** Each release reduces FP rate through better heuristics.\n\n---\n\n### **Q: \"Why Bash? Why not Python/Rust/Go?\"**\n\n**A:** Controversial choice, but intentional:\n\n**Advantages of Bash:**\n- ✅ **Zero dependencies** - runs on any Unix-like system\n- ✅ **Universal availability** - every dev machine has Bash 4.0+\n- ✅ **Shell integration** - git hooks, CI/CD, file watchers are natural\n- ✅ **Module system** - each language scanner is standalone\n- ✅ **Rapid prototyping** - adding new patterns is trivial\n- ✅ **LLM-readable** - AI agents can understand and modify rules\n\n**Disadvantages:**\n- ❌ Not as \"elegant\" as Python\n- ❌ String handling can be verbose\n- ❌ No static typing\n\n**Bottom line:** For a tool that orchestrates existing CLI tools (ripgrep, ast-grep, jq, typos) and needs to be universally available, Bash is pragmatic.\n\n**Future:** Core modules might be rewritten in Rust for speed, but the meta-runner will stay Bash for compatibility.\n\n---\n\n### **Q: \"Can I use this if I'm NOT using AI coding tools?\"**\n\n**A:** Absolutely! It's optimized for AI workflows, but works great for humans too.\n\n**Scenarios where humans love it:**\n\n**1. Code review speed-up**\n```bash\n# Reviewing a PR with 800+ lines\ngit checkout feature-branch\nubs .\n# Instantly see critical issues before deep review\n```\n\n**2. Legacy code audits**\n```bash\n# \"What's dangerous in this 10-year-old codebase?\"\nubs /path/to/legacy-app\n# Finds all the eval(), XSS, memory leaks\n```\n\n**3. Learning new languages**\n```bash\n# \"I'm new to Rust, what am I doing wrong?\"\nubs . --verbose\n# Shows common Rust pitfalls in your code\n```\n\n**4. Polyglot projects**\n```bash\n# Microservices in 5 languages\nubs .\n# One scan, all languages checked\n```\n\n**Humans appreciate:**\n- Zero setup (no config files to maintain)\n- Fast feedback (3s vs 30s)\n- Multi-language support (one command)\n- Finding bugs ESLint misses (deep guards)\n\n---\n\n### **Q: \"How is this different from security scanners like Snyk or GitHub Advanced Security?\"**\n\n**A:** Different focus and scope:\n\n**Security scanners (Snyk, Dependabot, etc.):**\n- Focus: **Dependency vulnerabilities**\n- Checks: npm packages, CVE databases\n- Speed: Seconds to minutes\n- Output: \"Update package X to fix CVE-2024-1234\"\n\n**UBS:**\n- Focus: **Code-level bugs** in YOUR code\n- Checks: Logic errors, null safety, memory leaks, security anti-patterns\n- Speed: 3-5 seconds\n- Output: \"You have unguarded null access at line 42\"\n\n**They're complementary:**\n```\n┌─────────────────────────────────────┐\n│  Complete Security Stack            │\n├─────────────────────────────────────┤\n│  Snyk/Dependabot  → Dependencies    │\n│  ✨ UBS            → Your code bugs │\n│  SAST tools       → Deep security   │\n│  GitHub Advanced  → Secrets in Git  │\n└─────────────────────────────────────┘\n```\n\n**Security scanners won't catch:** \"You forgot `await` and your async function silently fails.\"\n**UBS won't catch:** \"Your version of lodash has a known CVE.\"\n\nUse both.\n\n---\n\n### **Q: \"Will you support language X in the future?\"**\n\n**A:** Probably! The module system makes it easy to add languages.\n\n**Current:** JavaScript/TypeScript, Python, Go, Rust, Java, C++, Ruby, Swift, C#, Elixir (10 languages)\n\n**Roadmap considerations:**\n- **PHP** - High demand, lots of legacy code\n- **Kotlin** - Android development\n- **Scala** - JVM ecosystem\n- **Shell** - DevOps and installer scripts\n\n**How we prioritize:**\n1. Community demand (GitHub issues)\n2. AI coding tool usage (what LLMs generate most)\n3. Module maintainer availability\n\n**Want to contribute?** Writing a new module is ~800-1200 lines of Bash. Check the existing modules as templates.\n\n---\n\n### **Q: \"What's the catch? Why is this free?\"**\n\n**A:** No catch. It's MIT licensed.\n\n**Philosophy:**\n- Built by developers, for developers\n- AI coding is exploding, quality tools should be accessible\n- Open source enables community contributions (more patterns, better detection)\n\n**Business model:** None currently. This is a **community project**.\n\n**Future possibilities:**\n- Enterprise support contracts\n- Hosted version for teams\n- Premium modules for specific frameworks\n\nBut the core tool will always be free and open source.\n\n---\n\n## **The Bottom Line**\n\n**This isn't trying to replace ESLint.** It's solving a different problem:\n\n\u003e **\"How do I give LLM coding agents the ability to self-audit across 10 languages with zero configuration overhead and sub-5-second feedback?\"**\n\nNo existing tool does this because:\n- Traditional linters are human-first (need auto-fix, low FP tolerance)\n- They're single-language focused (polyglot = 7 different tools)\n- They're comprehensive, not fast (30s scan time kills AI iteration loops)\n- They're not designed for LLM consumption\n\n**UBS is purpose-built for the AI coding era.**\n\nUse it WITH your existing tools. Let ESLint handle style. Let TypeScript handle types. Let UBS catch the critical bugs that AI agents generate but can't see.\n\n---\n\n## 🧪 **Development \u0026 Internals**\n\n### **Python Tooling (uv + CPython 3.13)**\n\nAll helper scripts (manifest runner, fixtures, inline analyzers inside `ubs`) assume a single source of truth: **CPython 3.13 managed by [uv](https://github.com/astral-sh/uv)** living inside `.venv/` at the repo root.\n\n```bash\n# 1) Install uv (one-time)\ncurl -LsSf https://astral.sh/uv/install.sh | sh\n\n# 2) Create the managed environment defined by pyproject.toml / uv.lock\nuv sync --python 3.13\n\n# 3) Activate it whenever you work in this repo (puts .venv/bin first on PATH)\nsource .venv/bin/activate\n\n# 4) Run any Python entrypoint through the env\nuv run python test-suite/run_manifest.py --case js-core-buggy\n# ...or rely on 'python'/'python3' now that they point at .venv/bin/python3.13\n```\n\n\u003e [!NOTE]\n\u003e Shell scripts that invoke `python3` (language modules under `modules/`, `test-suite/run_all.sh`, etc.) automatically pick up `.venv/bin/python3` as long as the environment is activated or `.venv/bin` is on your `PATH`. The pinned `pyproject.toml` + `uv.lock` are the single source of truth for this toolchain.\n\nCommon uv-powered entrypoints:\n\n- `uv run python test-suite/run_manifest.py --case js-core-buggy` – run the manifest in CI or locally without manually activating the venv.\n- `source .venv/bin/activate \u0026\u0026 python -m pip list` – verify that every inline `python3` invocation maps to CPython 3.13.\n- `uv run python - \u003c\u003c'PY' …` – mirrors how the language modules embed Python helpers, but now guaranteed to execute inside the managed interpreter.\n\n---\n\n## 🚫 **Ignoring Paths with `.ubsignore`**\n\nNeed repo-wide scans to ignore generated code or intentionally buggy fixtures (like this project’s `test-suite/`)? Drop a `.ubsignore` at the root.\n\n- Format mirrors `.gitignore`: one glob per line, `#` for comments.\n- UBS loads `PROJECT/.ubsignore` automatically; override with `--ignore-file=/path/to/file`.\n- Built-in ignores already cover `node_modules`, virtualenvs, dist/build/target/vendor, editor caches, and more, so you rarely need to add them yourself.\n- Use `--suggest-ignore` to print large top-level directories that might deserve an entry (no files are modified automatically).\n- Inline suppression works for intentional one-offs: `eval(\"print('safe')\")  # ubs:ignore`.\n- Every language module receives the ignore list via their `--exclude` flag, so skips stay consistent.\n- This repository ships with a default `.ubsignore` that excludes `test-suite/`, keeping “real” source scans noise-free.\n\nExample:\n\n```text\n# Ignore fixtures + build output\ntest-suite/\ndist/\ncoverage/\n```\n\n---\n\n## 🧭 **Language Coverage Comparison**\n\nUBS ships ten language-focused analyzers. The comparison below focuses on the longest-standing mo","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdicklesworthstone%2Fultimate_bug_scanner","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdicklesworthstone%2Fultimate_bug_scanner","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdicklesworthstone%2Fultimate_bug_scanner/lists"}