pybinaryguard 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. pybinaryguard/__init__.py +78 -0
  2. pybinaryguard/__main__.py +7 -0
  3. pybinaryguard/_compat/__init__.py +0 -0
  4. pybinaryguard/agent/__init__.py +63 -0
  5. pybinaryguard/agent/guard.py +232 -0
  6. pybinaryguard/agent/recommender.py +283 -0
  7. pybinaryguard/agent/schema.py +200 -0
  8. pybinaryguard/agent/simulator.py +430 -0
  9. pybinaryguard/agent/tool_interface.py +474 -0
  10. pybinaryguard/analyzers/__init__.py +209 -0
  11. pybinaryguard/analyzers/base.py +40 -0
  12. pybinaryguard/analyzers/dependency_analyzer.py +336 -0
  13. pybinaryguard/analyzers/elf_analyzer.py +754 -0
  14. pybinaryguard/analyzers/symbol_analyzer.py +280 -0
  15. pybinaryguard/analyzers/wheel_analyzer.py +308 -0
  16. pybinaryguard/cli/__init__.py +5 -0
  17. pybinaryguard/cli/commands.py +414 -0
  18. pybinaryguard/cli/formatters.py +720 -0
  19. pybinaryguard/cli/main.py +250 -0
  20. pybinaryguard/diagnostics/__init__.py +13 -0
  21. pybinaryguard/diagnostics/explainer.py +356 -0
  22. pybinaryguard/diagnostics/findings.py +146 -0
  23. pybinaryguard/diagnostics/suggestions.py +508 -0
  24. pybinaryguard/frameworks/__init__.py +20 -0
  25. pybinaryguard/frameworks/onnxruntime.py +214 -0
  26. pybinaryguard/frameworks/pytorch.py +223 -0
  27. pybinaryguard/frameworks/tensorflow.py +266 -0
  28. pybinaryguard/frameworks/tensorrt.py +189 -0
  29. pybinaryguard/models/__init__.py +19 -0
  30. pybinaryguard/models/enums.py +102 -0
  31. pybinaryguard/models/finding.py +109 -0
  32. pybinaryguard/models/package.py +121 -0
  33. pybinaryguard/models/system.py +118 -0
  34. pybinaryguard/plugins/__init__.py +19 -0
  35. pybinaryguard/plugins/contrib/__init__.py +7 -0
  36. pybinaryguard/plugins/contrib/gstreamer.py +109 -0
  37. pybinaryguard/plugins/contrib/jetson.py +385 -0
  38. pybinaryguard/plugins/contrib/opencv.py +306 -0
  39. pybinaryguard/plugins/contrib/tensorrt.py +426 -0
  40. pybinaryguard/plugins/hooks.py +273 -0
  41. pybinaryguard/plugins/loader.py +190 -0
  42. pybinaryguard/predictor/__init__.py +23 -0
  43. pybinaryguard/predictor/dependency_graph.py +226 -0
  44. pybinaryguard/predictor/linker_simulator.py +161 -0
  45. pybinaryguard/predictor/predictor.py +144 -0
  46. pybinaryguard/predictor/resolver.py +282 -0
  47. pybinaryguard/probes/__init__.py +73 -0
  48. pybinaryguard/probes/base.py +45 -0
  49. pybinaryguard/probes/board_probe.py +248 -0
  50. pybinaryguard/probes/cpu_probe.py +176 -0
  51. pybinaryguard/probes/glibc_probe.py +215 -0
  52. pybinaryguard/probes/gpu_probe.py +430 -0
  53. pybinaryguard/probes/library_probe.py +132 -0
  54. pybinaryguard/probes/os_probe.py +227 -0
  55. pybinaryguard/probes/python_probe.py +135 -0
  56. pybinaryguard/probes/toolchain_probe.py +89 -0
  57. pybinaryguard/probes/venv_probe.py +111 -0
  58. pybinaryguard/profiles/__init__.py +12 -0
  59. pybinaryguard/profiles/engine.py +343 -0
  60. pybinaryguard/rules/__init__.py +24 -0
  61. pybinaryguard/rules/base.py +57 -0
  62. pybinaryguard/rules/builtin/__init__.py +136 -0
  63. pybinaryguard/rules/builtin/arch_rules.py +86 -0
  64. pybinaryguard/rules/builtin/board_profile_rules.py +282 -0
  65. pybinaryguard/rules/builtin/container_rules.py +170 -0
  66. pybinaryguard/rules/builtin/cpu_rules.py +204 -0
  67. pybinaryguard/rules/builtin/cuda_rules.py +760 -0
  68. pybinaryguard/rules/builtin/dependency_rules.py +278 -0
  69. pybinaryguard/rules/builtin/framework_rules.py +252 -0
  70. pybinaryguard/rules/builtin/glibc_rules.py +320 -0
  71. pybinaryguard/rules/builtin/numpy_rules.py +110 -0
  72. pybinaryguard/rules/builtin/predictive_rules.py +165 -0
  73. pybinaryguard/rules/builtin/python_abi_rules.py +259 -0
  74. pybinaryguard/rules/builtin/source_build_rules.py +150 -0
  75. pybinaryguard/rules/builtin/venv_rules.py +159 -0
  76. pybinaryguard/rules/engine.py +123 -0
  77. pybinaryguard/scanner.py +904 -0
  78. pybinaryguard/scoring/__init__.py +19 -0
  79. pybinaryguard/scoring/engine.py +416 -0
  80. pybinaryguard/snapshot/__init__.py +20 -0
  81. pybinaryguard/snapshot/generator.py +168 -0
  82. pybinaryguard/snapshot/lockfile.py +152 -0
  83. pybinaryguard/snapshot/verifier.py +315 -0
  84. pybinaryguard/validators/__init__.py +7 -0
  85. pybinaryguard/validators/import_validator.py +231 -0
  86. pybinaryguard-1.0.0.dist-info/METADATA +876 -0
  87. pybinaryguard-1.0.0.dist-info/RECORD +91 -0
  88. pybinaryguard-1.0.0.dist-info/WHEEL +5 -0
  89. pybinaryguard-1.0.0.dist-info/entry_points.txt +8 -0
  90. pybinaryguard-1.0.0.dist-info/licenses/LICENSE +21 -0
  91. pybinaryguard-1.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,876 @@
1
+ Metadata-Version: 2.4
2
+ Name: pybinaryguard
3
+ Version: 1.0.0
4
+ Summary: Binary Compatibility Intelligence for Python — detect incompatibilities before they crash your program
5
+ Author-email: S P Pothihai Selvan <po@nuvai.dev>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/Nuvai/pybinaryguard
8
+ Project-URL: Repository, https://github.com/Nuvai/pybinaryguard
9
+ Project-URL: Issues, https://github.com/Nuvai/pybinaryguard/issues
10
+ Project-URL: Changelog, https://github.com/Nuvai/pybinaryguard/blob/main/CHANGELOG.md
11
+ Keywords: binary,compatibility,elf,glibc,cuda,diagnostics
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Operating System :: POSIX :: Linux
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Software Development :: Quality Assurance
22
+ Classifier: Topic :: System :: Systems Administration
23
+ Requires-Python: >=3.9
24
+ Description-Content-Type: text/markdown
25
+ License-File: LICENSE
26
+ Provides-Extra: full
27
+ Requires-Dist: pyelftools>=0.29; extra == "full"
28
+ Provides-Extra: dev
29
+ Requires-Dist: pytest>=7.0; extra == "dev"
30
+ Requires-Dist: pytest-cov>=4.0; extra == "dev"
31
+ Requires-Dist: mypy>=1.0; extra == "dev"
32
+ Requires-Dist: ruff>=0.1.0; extra == "dev"
33
+ Dynamic: license-file
34
+
35
+ <p align="center">
36
+ <img src="https://img.shields.io/badge/python-3.9%2B-blue?style=for-the-badge&logo=python&logoColor=white" alt="Python 3.9+">
37
+ <img src="https://img.shields.io/badge/license-MIT-green?style=for-the-badge" alt="MIT License">
38
+ <img src="https://img.shields.io/badge/platform-linux-orange?style=for-the-badge&logo=linux&logoColor=white" alt="Linux">
39
+ <img src="https://img.shields.io/badge/version-1.0.0-purple?style=for-the-badge" alt="v1.0.0">
40
+ <img src="https://img.shields.io/badge/tests-505%20passing-brightgreen?style=for-the-badge" alt="505 Tests">
41
+ </p>
42
+
43
+ <h1 align="center">PyBinaryGuard</h1>
44
+
45
+ <p align="center">
46
+ <strong>Binary Compatibility Intelligence for Python</strong><br>
47
+ Detect incompatibilities <em>before</em> they crash your program.
48
+ </p>
49
+
50
+ <p align="center">
51
+ <a href="#quick-start">Quick Start</a> &bull;
52
+ <a href="#why-pybinaryguard">Why?</a> &bull;
53
+ <a href="#features">Features</a> &bull;
54
+ <a href="#cli-usage">CLI</a> &bull;
55
+ <a href="#python-api">Python API</a> &bull;
56
+ <a href="#agent-sdk">Agent SDK</a> &bull;
57
+ <a href="#architecture">Architecture</a>
58
+ </p>
59
+
60
+ ---
61
+
62
+ ## Origin Story
63
+
64
+ Back in college, I was working on real-time object detection on an **NVIDIA Jetson TX2** — computer vision, image processing, and ML models for live detection. I spent weeks writing the code. Tested the logic. Verified every layer, every weight, every preprocessing step. The code had **zero errors**.
65
+
66
+ Then I hit run.
67
+
68
+ ```
69
+ Illegal instruction (core dumped)
70
+ ```
71
+
72
+ That's it. No traceback. No helpful message. Just — *"instruction unclear, core dumped."*
73
+
74
+ I stared at the screen. I checked the code again. **Nothing was wrong.** I rewrote parts of it. Same crash. I tried different package versions. Same crash. I searched Stack Overflow for hours. Nothing worked.
75
+
76
+ This went on for **days**. Every single day, the same cryptic error. I started questioning my own code, my understanding of Python, everything. It was pure rage.
77
+
78
+ Then one day I finally figured it out — it wasn't my code at all. The pip packages I installed were compiled for a different architecture. The CUDA toolkit version didn't match what PyTorch expected. The GLIBC on the Jetson was too old for the prebuilt wheels. The binaries simply didn't belong on that hardware.
79
+
80
+ **My code was perfect. The binaries were incompatible.**
81
+
82
+ And the worst part? There was no tool to tell me this. No `pip check` that catches binary mismatches. No scanner that says *"hey, this .so file needs GLIBC 2.34 but you only have 2.27."* Nothing.
83
+
84
+ I told myself: if I ever get the chance, I'll build the tool I wish I had during those sleepless nights on the Jetson. Something that looks at your system — your CPU, your GPU, your GLIBC, your CUDA — and tells you **what's actually wrong** before you waste another day blaming your own code.
85
+
86
+ That tool is **PyBinaryGuard**.
87
+
88
+ ---
89
+
90
+ ## The Problem
91
+
92
+ You install a Python package. Your code is correct. Your machine is fine. **It still crashes.**
93
+
94
+ ```
95
+ ImportError: /lib/x86_64-linux-gnu/libm.so.6: version `GLIBC_2.34' not found
96
+ ```
97
+
98
+ ```
99
+ Illegal instruction (core dumped)
100
+ ```
101
+
102
+ ```
103
+ OSError: libcudart.so.12: cannot open shared object file
104
+ ```
105
+
106
+ These aren't bugs in your code. They're **binary-level incompatibilities** between compiled C/C++ libraries inside Python packages and your system's hardware, OS, or drivers. No existing tool catches them before runtime.
107
+
108
+ **PyBinaryGuard does.**
109
+
110
+ ---
111
+
112
+ ## Why PyBinaryGuard?
113
+
114
+ | Tool | What it does | What it misses |
115
+ |------|-------------|----------------|
116
+ | `pip check` | Version conflicts | Binary/ABI compatibility |
117
+ | `ldd` | Shared library links | Python package context |
118
+ | `nvidia-smi` | GPU info | Cross-package CUDA conflicts |
119
+ | `file` | ELF metadata | Compatibility analysis |
120
+ | **PyBinaryGuard** | **All of the above, unified** | -- |
121
+
122
+ PyBinaryGuard is the **first tool** that correlates your Python version, CPU architecture, GLIBC version, CUDA toolkit, GPU compute capability, and installed package binaries into a single compatibility verdict.
123
+
124
+ ---
125
+
126
+ ## Quick Start
127
+
128
+ ```bash
129
+ # Clone and install
130
+ git clone https://github.com/vikash-nuvai/pybinaryguard.git
131
+ cd pybinaryguard
132
+ pip install -e .
133
+
134
+ # Run a full scan
135
+ pybinaryguard scan
136
+
137
+ # Check a specific package
138
+ pybinaryguard check torch
139
+
140
+ # Fast scan (metadata only, <1 second)
141
+ pybinaryguard scan --fast
142
+
143
+ # Deep scan (full symbol resolution + hash verification)
144
+ pybinaryguard scan --deep
145
+ ```
146
+
147
+ ---
148
+
149
+ ## Features
150
+
151
+ ### Core Scanner
152
+ - **System Profiling** -- Detects Python version, CPU architecture (x86_64/aarch64/armv7l), GLIBC version, CUDA toolkit, GPU compute capability, container environment
153
+ - **Binary Analysis** -- Inspects `.so` shared objects inside installed packages using ELF header parsing and symbol resolution
154
+ - **20+ Built-in Rules** -- Covers GLIBC version requirements, CUDA ABI mismatches, CPU instruction set conflicts, architecture mismatches, NumPy ABI breaks, container-specific issues, and more
155
+ - **Plugin System** -- Extensible with custom probes, analyzers, and rules for Jetson, TensorRT, OpenCV, GStreamer
156
+
157
+ ### Health Scoring v2
158
+ Multi-dimensional weighted scoring across 4 categories:
159
+
160
+ | Category | Weight | What it measures |
161
+ |----------|--------|------------------|
162
+ | Binary Stability | 35% | GLIBC, ELF, ABI issues |
163
+ | GPU Compatibility | 30% | CUDA, compute capability, driver mismatches |
164
+ | Dependency Health | 25% | Version conflicts, missing libraries |
165
+ | Platform Risk | 10% | Architecture, container, OS-specific issues |
166
+
167
+ Weights auto-adjust based on your system (e.g., no GPU = GPU weight redistributed).
168
+
169
+ ### Scan Modes
170
+
171
+ | Mode | Speed | Depth | Use case |
172
+ |------|-------|-------|----------|
173
+ | `--fast` | <1s | Metadata only, skips ELF analysis | CI pipelines, quick checks |
174
+ | *(default)* | ~3s | Full binary analysis | Development workflow |
175
+ | `--deep` | ~10s | Symbol resolution + SHA256 hashes | Security audits, production deploys |
176
+
177
+ ### Board Profile Engine
178
+ Built-in support for embedded/edge platforms:
179
+ - **NVIDIA Jetson** (Nano, TX2, Xavier, Orin)
180
+ - **Raspberry Pi** (3B, 4B, 5, Zero 2W)
181
+ - Custom board profiles via plugin system
182
+
183
+ ### AI Framework Inspection
184
+ Specialized checks for ML/AI stacks:
185
+ - PyTorch CUDA ABI compatibility
186
+ - PyTorch + TorchVision version matrix
187
+ - TensorFlow compute capability requirements
188
+ - TensorRT version compatibility
189
+ - ONNX Runtime execution provider validation
190
+
191
+ ### Predictive Failure Engine
192
+ Predicts runtime failures before they happen:
193
+ - Import error prediction based on dependency chain analysis
194
+ - Unresolved symbol detection
195
+ - Cross-package ABI conflict detection
196
+
197
+ ### Environment Snapshots
198
+ Lock and verify your binary environment:
199
+
200
+ ```bash
201
+ # Create a snapshot
202
+ pybinaryguard snapshot -o env.lock.json
203
+
204
+ # Verify against snapshot on another machine
205
+ pybinaryguard verify env.lock.json
206
+ ```
207
+
208
+ ---
209
+
210
+ ## CLI Usage
211
+
212
+ ```
213
+ pybinaryguard <command> [options]
214
+
215
+ Commands:
216
+ scan Full environment scan
217
+ check <package> Check a specific package
218
+ profile Show system profile
219
+ doctor Interactive troubleshooting
220
+ inspect <file> Analyse a .whl or .so file
221
+ snapshot Create environment snapshot
222
+ verify <lockfile> Verify against snapshot
223
+ simulate <spec> Predict compatibility before install
224
+ export-tool-schema Export agent tool schema
225
+
226
+ Global Options:
227
+ --format {table,json,minimal} Output format (default: table)
228
+ --severity {critical,warning,info,all}
229
+ --fast / --deep Scan depth
230
+ --ci CI mode (minimal + strict exit codes)
231
+ --ignore RULE_ID [...] Rules to skip
232
+ --timeout SECONDS Max scan time (default: 30)
233
+ --no-color Disable coloured output
234
+ -v, --verbose Show technical details
235
+ -q, --quiet Critical findings only
236
+ ```
237
+
238
+ ### Exit Codes
239
+
240
+ | Code | Meaning |
241
+ |------|---------|
242
+ | 0 | All clear |
243
+ | 1 | Warnings found |
244
+ | 2 | Critical issues found |
245
+ | 3 | Scanner error |
246
+
247
+ ### CI/CD Integration
248
+
249
+ ```yaml
250
+ # GitHub Actions
251
+ - name: Binary compatibility check
252
+ run: |
253
+ pip install pybinaryguard
254
+ pybinaryguard scan --ci
255
+ ```
256
+
257
+ ```Dockerfile
258
+ # Docker health check
259
+ HEALTHCHECK CMD pybinaryguard scan --fast --ci || exit 1
260
+ ```
261
+
262
+ ---
263
+
264
+ ## Python API
265
+
266
+ ```python
267
+ import pybinaryguard
268
+
269
+ # Full environment scan
270
+ report = pybinaryguard.scan()
271
+ print(f"Health: {report.health_score}/100")
272
+ print(f"Issues: {report.total_findings}")
273
+
274
+ for finding in report.findings:
275
+ print(f"[{finding.severity}] {finding.rule_id}: {finding.message}")
276
+ if finding.suggestion:
277
+ print(f" Fix: {finding.suggestion}")
278
+
279
+ # Check a single package
280
+ findings = pybinaryguard.check("torch")
281
+
282
+ # Get system profile
283
+ profile = pybinaryguard.profile()
284
+ print(f"Python: {profile.python_version}")
285
+ print(f"GLIBC: {profile.glibc_version}")
286
+ print(f"Arch: {profile.architecture}")
287
+ print(f"CUDA: {profile.cuda_version}")
288
+
289
+ # Inspect a wheel file before installing
290
+ findings = pybinaryguard.inspect("torch-2.4.0-cp311-cp311-manylinux1_x86_64.whl")
291
+ ```
292
+
293
+ ---
294
+
295
+ ## Agent SDK
296
+
297
+ PyBinaryGuard is **agent-native** -- designed for AI agents and automation pipelines to consume directly.
298
+
299
+ ### Structured Output
300
+
301
+ ```python
302
+ from pybinaryguard.agent import scan, check, simulate_install, doctor
303
+
304
+ # Returns machine-readable ActionableReport
305
+ report = scan()
306
+ report.to_dict() # JSON-serializable
307
+
308
+ # Classified actions with safety levels
309
+ report.safe_actions # Auto-executable (e.g., pip install --upgrade)
310
+ report.review_actions # Needs human confirmation
311
+ report.dangerous_actions # Human-only (e.g., system library changes)
312
+
313
+ # Pre-install simulation
314
+ sim = simulate_install("torch==2.4.0+cu124")
315
+ sim.predicted_compatible # True/False
316
+ sim.confidence # 0.0-1.0
317
+ sim.blockers # List of blocking issues
318
+
319
+ # Error diagnosis
320
+ dx = doctor("GLIBC_2.34 not found")
321
+ dx.diagnosis # What went wrong
322
+ dx.fix_plan # Step-by-step fix
323
+ dx.auto_fix_safe # Can an agent fix this automatically?
324
+ ```
325
+
326
+ ### Tool Schema Export
327
+
328
+ Register PyBinaryGuard as a tool in any agent framework:
329
+
330
+ ```python
331
+ from pybinaryguard.agent import export_tool_schema
332
+
333
+ # OpenAI function calling format
334
+ schema = export_tool_schema(format="openai")
335
+
336
+ # MCP (Model Context Protocol) format
337
+ schema = export_tool_schema(format="mcp")
338
+
339
+ # Generic JSON Schema
340
+ schema = export_tool_schema(format="json_schema")
341
+ ```
342
+
343
+ ```bash
344
+ # CLI export
345
+ pybinaryguard export-tool-schema --schema-format openai
346
+ pybinaryguard export-tool-schema --schema-format mcp
347
+ ```
348
+
349
+ ### One-Liner Agent Registration
350
+
351
+ ```python
352
+ from pybinaryguard.agent import as_agent_tool
353
+
354
+ # Returns {schema: ..., handlers: {scan: fn, check: fn, ...}}
355
+ tool = as_agent_tool()
356
+ ```
357
+
358
+ ### Runtime Import Guard
359
+
360
+ Capture and diagnose import failures in real-time:
361
+
362
+ ```python
363
+ from pybinaryguard.agent.guard import guarded_imports
364
+
365
+ with guarded_imports() as guard:
366
+ import torch # If this fails, guard captures structured diagnostics
367
+
368
+ for error in guard.captured_errors:
369
+ print(error["category"]) # e.g., "glibc_mismatch"
370
+ print(error["diagnosis"]) # Human-readable explanation
371
+ ```
372
+
373
+ ---
374
+
375
+ ## How It Works (UML Diagrams)
376
+
377
+ ### Core Scan Pipeline
378
+
379
+ The entire library follows a 4-phase pipeline: **Probe → Analyze → Evaluate → Report**.
380
+
381
+ ```mermaid
382
+ flowchart TB
383
+ subgraph INPUT["INPUT"]
384
+ USER["User / Agent / CI"]
385
+ end
386
+
387
+ subgraph PHASE1["PHASE 1: PROBE — Collect System Info"]
388
+ direction LR
389
+ PP["PythonProbe<br/>Python version, ABI"]
390
+ CP["CpuProbe<br/>Architecture, ISA"]
391
+ GP["GlibcProbe<br/>GLIBC version"]
392
+ GPU["GpuProbe<br/>CUDA, GPU, compute cap"]
393
+ OP["OsProbe<br/>OS, container detect"]
394
+ LP["LibraryProbe<br/>System shared libs"]
395
+ BP["BoardProbe<br/>Jetson, RPi detect"]
396
+ end
397
+
398
+ subgraph PROFILE["SystemProfile"]
399
+ SP["python_version<br/>architecture<br/>glibc_version<br/>cuda_version<br/>gpu_name<br/>compute_capability<br/>os_name<br/>is_container<br/>..."]
400
+ end
401
+
402
+ subgraph PHASE2["PHASE 2: ANALYZE — Inspect Package Binaries"]
403
+ direction LR
404
+ WA["WheelAnalyzer<br/>WHEEL metadata, tags"]
405
+ EA["ELF Analyzer<br/>Headers, symbols, DT_NEEDED"]
406
+ SA["SymbolAnalyzer<br/>Unresolved symbols"]
407
+ DA["DependencyAnalyzer<br/>Dependency chain"]
408
+ end
409
+
410
+ subgraph PACKAGES["PackageBinaryInfo[]"]
411
+ PKG["package_name<br/>shared_objects[]<br/>wheel_tags[]<br/>required_glibc<br/>target_architecture<br/>..."]
412
+ end
413
+
414
+ subgraph PHASE3["PHASE 3: EVALUATE — Run Compatibility Rules"]
415
+ direction LR
416
+ RE["RuleEngine"]
417
+ R1["GLIBC Rules"]
418
+ R2["CUDA Rules"]
419
+ R3["Arch Rules"]
420
+ R4["CPU Rules"]
421
+ R5["NumPy ABI Rules"]
422
+ R6["Container Rules"]
423
+ R7["Framework Rules<br/>PyTorch, TF, TRT, ONNX"]
424
+ R8["Board Rules<br/>Jetson, RPi"]
425
+ R9["Predictive Rules"]
426
+ end
427
+
428
+ subgraph FINDINGS["Finding[]"]
429
+ F["rule_id<br/>severity<br/>package<br/>message<br/>suggestion<br/>confidence"]
430
+ end
431
+
432
+ subgraph PHASE4["PHASE 4: REPORT — Score & Format"]
433
+ direction LR
434
+ HS["HealthScoreV2<br/>4-category weighted"]
435
+ FMT["Formatter<br/>Table / JSON / Minimal"]
436
+ AGENT["Agent SDK<br/>ActionRecommender"]
437
+ end
438
+
439
+ subgraph OUTPUT["OUTPUT"]
440
+ SR["ScanReport<br/>health_score: 73/100<br/>findings: [...]<br/>score_breakdown: {...}"]
441
+ end
442
+
443
+ USER -->|"scan() / check() / CLI"| PHASE1
444
+ PP & CP & GP & GPU & OP & LP & BP -->|"parallel threads"| PROFILE
445
+ PROFILE --> PHASE2
446
+ WA & EA & SA & DA -->|"per package"| PACKAGES
447
+ PROFILE --> PHASE3
448
+ PACKAGES --> PHASE3
449
+ RE --> R1 & R2 & R3 & R4 & R5 & R6 & R7 & R8 & R9
450
+ PHASE3 --> FINDINGS
451
+ FINDINGS --> PHASE4
452
+ HS & FMT & AGENT --> OUTPUT
453
+ OUTPUT --> USER
454
+ ```
455
+
456
+ ### Sequence Diagram — Full Scan Flow
457
+
458
+ Step-by-step execution when a user runs `pybinaryguard scan`:
459
+
460
+ ```mermaid
461
+ sequenceDiagram
462
+ actor User
463
+ participant CLI as CLI (main.py)
464
+ participant CMD as Commands (commands.py)
465
+ participant Scanner
466
+ participant Probes as Probes (7 probes)
467
+ participant Analyzers as ELF/Wheel Analyzers
468
+ participant Rules as Rule Engine (20+ rules)
469
+ participant Scoring as HealthScoreV2
470
+ participant Formatter as Table/JSON Formatter
471
+
472
+ User->>CLI: pybinaryguard scan
473
+ CLI->>CMD: dispatch(args)
474
+ CMD->>Scanner: Scanner(scan_mode, ...).run()
475
+
476
+ Note over Scanner: PHASE 1: PROBE
477
+ Scanner->>Probes: run all probes (parallel threads)
478
+ Probes-->>Scanner: merged dict
479
+ Scanner->>Scanner: build SystemProfile
480
+
481
+ Note over Scanner: PHASE 2: ANALYZE
482
+ Scanner->>Scanner: walk site-packages dirs
483
+ loop Each package with .dist-info
484
+ Scanner->>Analyzers: parse WHEEL tags
485
+ alt STANDARD or DEEP mode
486
+ Scanner->>Analyzers: parse ELF headers (.so files)
487
+ Analyzers-->>Scanner: SharedObjectInfo[]
488
+ end
489
+ alt DEEP mode only
490
+ Scanner->>Scanner: compute SHA256 hashes
491
+ end
492
+ end
493
+ Scanner-->>Scanner: PackageBinaryInfo[]
494
+
495
+ Note over Scanner: PHASE 3: EVALUATE
496
+ Scanner->>Rules: RuleEngine.with_builtin_rules()
497
+ loop Each rule
498
+ Rules->>Rules: is_applicable(profile)?
499
+ alt applicable
500
+ Rules->>Rules: evaluate(profile, packages)
501
+ Rules-->>Scanner: Finding[]
502
+ end
503
+ end
504
+
505
+ Note over Scanner: PHASE 4: REPORT
506
+ Scanner->>Scoring: compute_health_score(findings)
507
+ Scoring-->>Scanner: ScoreBreakdown
508
+ Scanner->>Scanner: deduplicate, filter, sort
509
+ Scanner-->>CMD: ScanReport
510
+
511
+ CMD->>Formatter: format_scan(report, profile)
512
+ Formatter-->>CMD: formatted string
513
+ CMD-->>CLI: exit code (0/1/2)
514
+ CLI-->>User: printed output
515
+ ```
516
+
517
+ ### Health Scoring Model
518
+
519
+ How the multi-dimensional health score is calculated:
520
+
521
+ ```mermaid
522
+ flowchart LR
523
+ subgraph FINDINGS["All Findings"]
524
+ F1["GLIBC_VERSION_MISMATCH<br/>severity: CRITICAL"]
525
+ F2["CUDA_MINOR_MISMATCH<br/>severity: WARNING"]
526
+ F3["NUMPY_ABI_MISMATCH<br/>severity: WARNING"]
527
+ F4["CONTAINER_GLIBC_OLD<br/>severity: INFO"]
528
+ end
529
+
530
+ subgraph CLASSIFY["Classify by Rule ID Prefix"]
531
+ C1["binary_stability<br/>GLIBC_, ARCH_, ELF_, ..."]
532
+ C2["gpu_compat<br/>CUDA_, PYTORCH_CUDA_, ..."]
533
+ C3["dependency_health<br/>NUMPY_ABI_, MISSING_, ..."]
534
+ C4["platform_risk<br/>CONTAINER_, BOARD_, ..."]
535
+ end
536
+
537
+ subgraph SCORE["Score Each Category"]
538
+ S1["Binary: 70/100<br/>weight: 0.35"]
539
+ S2["GPU: 90/100<br/>weight: 0.30"]
540
+ S3["Deps: 90/100<br/>weight: 0.25"]
541
+ S4["Platform: 98/100<br/>weight: 0.10"]
542
+ end
543
+
544
+ subgraph TOTAL["Weighted Total"]
545
+ T["70x0.35 + 90x0.30 + 90x0.25 + 98x0.10<br/>= 24.5 + 27.0 + 22.5 + 9.8<br/>= <strong>83.8 / 100</strong>"]
546
+ end
547
+
548
+ F1 --> C1
549
+ F2 --> C2
550
+ F3 --> C3
551
+ F4 --> C4
552
+
553
+ C1 --> S1
554
+ C2 --> S2
555
+ C3 --> S3
556
+ C4 --> S4
557
+
558
+ S1 & S2 & S3 & S4 --> T
559
+ ```
560
+
561
+ ### Agent SDK Flow
562
+
563
+ How AI agents interact with PyBinaryGuard:
564
+
565
+ ```mermaid
566
+ flowchart TB
567
+ subgraph AGENT["AI Agent (GPT, LangChain, AutoGen, CrewAI, etc.)"]
568
+ A1["1. Register tool via schema"]
569
+ A2["2. Call scan/check/simulate/doctor"]
570
+ A3["3. Read structured result"]
571
+ A4["4. Execute safe_actions automatically"]
572
+ A5["5. Ask human for review_actions"]
573
+ end
574
+
575
+ subgraph SDK["PyBinaryGuard Agent SDK"]
576
+ SCHEMA["export_tool_schema()<br/>OpenAI / MCP / JSON Schema"]
577
+ SCAN["scan() → ActionableReport"]
578
+ CHECK["check('torch') → AgentCheckResult"]
579
+ SIM["simulate_install('torch==2.4.0+cu124')<br/>→ AgentSimulateResult"]
580
+ DOC["doctor('GLIBC_2.34 not found')<br/>→ AgentDoctorResult"]
581
+ REC["ActionRecommender<br/>classify actions by safety"]
582
+ end
583
+
584
+ subgraph SAFETY["Action Safety Classification"]
585
+ SAFE["SAFE (auto-execute)<br/>pip install --upgrade numpy<br/>pip install torch==2.3.0"]
586
+ REVIEW["REVIEW (confirm first)<br/>pip install --force-reinstall ...<br/>pip install package[cuda12]"]
587
+ DANGER["DANGEROUS (human only)<br/>apt install libcuda1<br/>System library changes"]
588
+ end
589
+
590
+ A1 -->|"schema = export_tool_schema('openai')"| SCHEMA
591
+ A2 --> SCAN & CHECK & SIM & DOC
592
+ SCAN --> REC
593
+ REC --> SAFE & REVIEW & DANGER
594
+ SAFE --> A4
595
+ REVIEW --> A5
596
+ DANGER -->|"flag to human"| A5
597
+ A3 -->|"result.to_dict() → JSON"| A2
598
+ ```
599
+
600
+ ### Scan Mode Comparison
601
+
602
+ ```mermaid
603
+ flowchart LR
604
+ subgraph FAST["--fast (<1 second)"]
605
+ F1_["Read WHEEL metadata"]
606
+ F2_["Check .so file existence"]
607
+ F3_["Run metadata-only rules"]
608
+ F4_["Skip ELF parsing entirely"]
609
+ end
610
+
611
+ subgraph STD["default (~3 seconds)"]
612
+ S1_["Read WHEEL metadata"]
613
+ S2_["Parse ELF headers"]
614
+ S3_["Extract DT_NEEDED, symbols"]
615
+ S4_["Run ALL rules"]
616
+ end
617
+
618
+ subgraph DEEP["--deep (~10 seconds)"]
619
+ D1_["Read WHEEL metadata"]
620
+ D2_["Parse ELF headers"]
621
+ D3_["Full symbol resolution"]
622
+ D4_["SHA256 hash every .so"]
623
+ D5_["Run ALL rules"]
624
+ end
625
+
626
+ F1_ --> F2_ --> F3_ --> F4_
627
+ S1_ --> S2_ --> S3_ --> S4_
628
+ D1_ --> D2_ --> D3_ --> D4_ --> D5_
629
+ ```
630
+
631
+ ### Class Diagram — Core Data Model
632
+
633
+ ```mermaid
634
+ classDiagram
635
+ class SystemProfile {
636
+ +str python_version
637
+ +str architecture
638
+ +str glibc_version
639
+ +str cuda_version
640
+ +str gpu_name
641
+ +float compute_capability
642
+ +str os_name
643
+ +bool is_container
644
+ +bool gpu_available
645
+ +bool is_embedded_board
646
+ +list site_packages_paths
647
+ }
648
+
649
+ class PackageBinaryInfo {
650
+ +str package_name
651
+ +str package_version
652
+ +str install_path
653
+ +list~SharedObjectInfo~ shared_objects
654
+ +list~WheelTag~ wheel_tags
655
+ +str required_glibc
656
+ +str target_architecture
657
+ +bool has_binaries
658
+ +bool is_pure_python
659
+ }
660
+
661
+ class SharedObjectInfo {
662
+ +str name
663
+ +str path
664
+ +str architecture
665
+ +str required_glibc
666
+ +list~str~ dt_needed
667
+ +str sha256
668
+ }
669
+
670
+ class Finding {
671
+ +str rule_id
672
+ +Severity severity
673
+ +str title
674
+ +str explanation
675
+ +str package
676
+ +str suggestion
677
+ +float confidence
678
+ }
679
+
680
+ class ScanReport {
681
+ +list~Finding~ findings
682
+ +int packages_scanned
683
+ +int total_packages
684
+ +float scan_duration_ms
685
+ +ScoreBreakdown score_breakdown
686
+ +int health_score
687
+ +str health_label
688
+ +int critical_count
689
+ +int warning_count
690
+ }
691
+
692
+ class ScoreBreakdown {
693
+ +float overall_score
694
+ +str overall_label
695
+ +dict categories
696
+ +int total_findings
697
+ +CategoryScore weakest_category
698
+ }
699
+
700
+ class CategoryScore {
701
+ +str name
702
+ +float score
703
+ +float weight
704
+ +float weighted_score
705
+ +str label
706
+ +list top_issues
707
+ }
708
+
709
+ class Rule {
710
+ <<abstract>>
711
+ +str rule_id
712
+ +Severity severity
713
+ +is_applicable(SystemProfile) bool
714
+ +evaluate(SystemProfile, list) list~Finding~
715
+ }
716
+
717
+ class Scanner {
718
+ +run() ScanReport
719
+ +check_package(str) list~Finding~
720
+ +get_profile() SystemProfile
721
+ +inspect_file(str) list~Finding~
722
+ }
723
+
724
+ Scanner --> SystemProfile : collects
725
+ Scanner --> PackageBinaryInfo : analyzes
726
+ Scanner --> Rule : evaluates
727
+ Rule --> Finding : produces
728
+ Scanner --> ScanReport : builds
729
+ ScanReport --> Finding : contains
730
+ ScanReport --> ScoreBreakdown : includes
731
+ ScoreBreakdown --> CategoryScore : has 4
732
+ PackageBinaryInfo --> SharedObjectInfo : contains
733
+ ```
734
+
735
+ ---
736
+
737
+ ## Project Structure
738
+
739
+ ```
740
+ pybinaryguard/
741
+ |
742
+ |-- pyproject.toml # Packaging config (PEP 621)
743
+ |-- README.md
744
+ |-- LICENSE
745
+ |-- CHANGELOG.md
746
+ |-- .gitignore
747
+ |
748
+ |-- src/
749
+ | +-- pybinaryguard/
750
+ | |-- __init__.py # Public API (scan, check, profile, inspect)
751
+ | |-- scanner.py # Core orchestrator
752
+ | |
753
+ | |-- models/ # Data structures
754
+ | | |-- system.py # SystemProfile dataclass
755
+ | | |-- finding.py # Finding, ScanReport
756
+ | | |-- package.py # PackageBinaryInfo, SharedObjectInfo
757
+ | | +-- enums.py # Severity, ScanMode
758
+ | |
759
+ | |-- probes/ # System information collectors
760
+ | | |-- os_probe.py # OS, GLIBC, container detection
761
+ | | |-- python_probe.py # Python version, ABI flags
762
+ | | |-- cpu_probe.py # Architecture, instruction sets
763
+ | | |-- gpu_probe.py # CUDA, GPU compute capability
764
+ | | |-- glibc_probe.py # GLIBC version detection
765
+ | | |-- library_probe.py # System shared library inventory
766
+ | | +-- board_probe.py # Embedded board detection (Jetson, RPi)
767
+ | |
768
+ | |-- analyzers/ # Package binary inspectors
769
+ | | |-- elf_analyzer.py # ELF header & symbol table parsing
770
+ | | |-- wheel_analyzer.py
771
+ | | |-- symbol_analyzer.py
772
+ | | +-- dependency_analyzer.py
773
+ | |
774
+ | |-- rules/ # Compatibility rule engine
775
+ | | |-- engine.py # Rule evaluation orchestrator
776
+ | | +-- builtin/ # 20+ built-in rules
777
+ | | |-- glibc_rules.py
778
+ | | |-- cuda_rules.py
779
+ | | |-- arch_rules.py
780
+ | | |-- cpu_rules.py
781
+ | | |-- numpy_rules.py
782
+ | | |-- container_rules.py
783
+ | | |-- python_abi_rules.py
784
+ | | |-- board_profile_rules.py
785
+ | | |-- framework_rules.py
786
+ | | +-- predictive_rules.py
787
+ | |
788
+ | |-- scoring/ # Health scoring v2
789
+ | | +-- engine.py # Multi-dimensional weighted scoring
790
+ | |
791
+ | |-- profiles/ # Board profile engine
792
+ | | +-- engine.py # Board detection & matching
793
+ | |
794
+ | |-- diagnostics/ # Error explanation
795
+ | | |-- findings.py
796
+ | | |-- explainer.py
797
+ | | +-- suggestions.py
798
+ | |
799
+ | |-- agent/ # Agent SDK
800
+ | | |-- tool_interface.py
801
+ | | |-- recommender.py
802
+ | | |-- schema.py # Tool schema export (OpenAI/MCP)
803
+ | | |-- simulator.py # Pre-install compatibility prediction
804
+ | | +-- guard.py # Runtime import guard
805
+ | |
806
+ | |-- plugins/ # Plugin system
807
+ | | |-- loader.py
808
+ | | |-- hooks.py
809
+ | | +-- contrib/ # Built-in plugins (Jetson, TensorRT, OpenCV, GStreamer)
810
+ | |
811
+ | +-- cli/ # Command-line interface
812
+ | |-- main.py # Argument parser
813
+ | |-- commands.py # Command handlers
814
+ | +-- formatters.py # Output formatting (table/json/minimal)
815
+ |
816
+ |-- tests/ # 450 tests
817
+ |-- docs/ # Documentation
818
+ +-- examples/ # Usage examples
819
+ ```
820
+
821
+ ### Design Principles
822
+
823
+ 1. **Zero dependencies by default** -- Core functionality works with just the Python standard library. Optional `pyelftools` enables deep ELF analysis.
824
+
825
+ 2. **Read-only** -- Never modifies your system, packages, or files. Safe to run anywhere.
826
+
827
+ 3. **Offline-first** -- No network calls. All analysis runs locally. Works in air-gapped environments.
828
+
829
+ 4. **Agent-native** -- Structured JSON-serializable outputs. Tool schema export. Safety-classified actions.
830
+
831
+ 5. **Extensible** -- Plugin system for custom probes, analyzers, and rules via entry points.
832
+
833
+ ---
834
+
835
+ ## Supported Platforms
836
+
837
+ | Platform | Architecture | Status |
838
+ |----------|-------------|--------|
839
+ | Ubuntu 20.04+ | x86_64 | Fully supported |
840
+ | Ubuntu 20.04+ | aarch64 | Fully supported |
841
+ | Debian 11+ | x86_64 / aarch64 | Fully supported |
842
+ | RHEL / CentOS 8+ | x86_64 | Supported |
843
+ | Alpine (musl) | x86_64 | Supported |
844
+ | NVIDIA Jetson | aarch64 | Supported (board profiles) |
845
+ | Raspberry Pi OS | armv7l / aarch64 | Supported (board profiles) |
846
+ | Docker containers | any | Supported (auto-detected) |
847
+
848
+ ---
849
+
850
+ ## Testing
851
+
852
+ ```bash
853
+ # Run all tests (450 tests)
854
+ python -m pytest tests/ -v
855
+
856
+ # Run with coverage
857
+ python -m pytest tests/ --cov=pybinaryguard --cov-report=term-missing
858
+
859
+ # Run specific test suites
860
+ python -m pytest tests/test_scoring.py -v # Health scoring
861
+ python -m pytest tests/test_scan_modes.py -v # Scan modes
862
+ python -m pytest tests/test_agent_sdk.py -v # Agent SDK
863
+ ```
864
+
865
+ ---
866
+
867
+ ## Author
868
+
869
+ **S P Pothihai Selvan** (Po-nuvai)
870
+ Applied Research Scientist @ [Nuvai AI Solution Pvt Ltd](https://nuvai.dev)
871
+
872
+ ---
873
+
874
+ ## License
875
+
876
+ MIT License. See [LICENSE](LICENSE) for details.