codesuture 0.7.3__tar.gz → 1.0.0__tar.gz

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 (95) hide show
  1. codesuture-1.0.0/LICENSE +21 -0
  2. codesuture-1.0.0/MANIFEST.in +18 -0
  3. codesuture-1.0.0/PKG-INFO +430 -0
  4. codesuture-1.0.0/README.md +405 -0
  5. codesuture-1.0.0/assets/architecture.png +0 -0
  6. codesuture-1.0.0/assets/guards.png +0 -0
  7. codesuture-1.0.0/assets/hero.png +0 -0
  8. codesuture-1.0.0/codesuture/__init__.py +1 -0
  9. codesuture-1.0.0/codesuture/alerts/__init__.py +2 -0
  10. codesuture-1.0.0/codesuture/alerts/channels/__init__.py +1 -0
  11. codesuture-1.0.0/codesuture/alerts/channels/file_channel.py +139 -0
  12. codesuture-1.0.0/codesuture/alerts/channels/webhook_channel.py +98 -0
  13. codesuture-1.0.0/codesuture/alerts/config.py +80 -0
  14. codesuture-1.0.0/codesuture/alerts/router.py +129 -0
  15. {codesuture-0.7.3 → codesuture-1.0.0}/codesuture/audit.py +90 -124
  16. codesuture-1.0.0/codesuture/cli.py +570 -0
  17. {codesuture-0.7.3 → codesuture-1.0.0}/codesuture/codesuture_fix.py +1 -1
  18. {codesuture-0.7.3 → codesuture-1.0.0}/codesuture/explain.py +114 -147
  19. {codesuture-0.7.3 → codesuture-1.0.0}/codesuture/fingerprint.py +2 -1
  20. {codesuture-0.7.3 → codesuture-1.0.0}/codesuture/guard_synthesizer.py +95 -17
  21. codesuture-1.0.0/codesuture/incidents/__init__.py +4 -0
  22. codesuture-1.0.0/codesuture/incidents/digest.py +136 -0
  23. codesuture-1.0.0/codesuture/incidents/incident.py +87 -0
  24. codesuture-1.0.0/codesuture/incidents/incident_log.py +79 -0
  25. codesuture-1.0.0/codesuture/incidents/severity.py +45 -0
  26. codesuture-1.0.0/codesuture/lifecycle.py +203 -0
  27. codesuture-1.0.0/codesuture/metrics.py +124 -0
  28. {codesuture-0.7.3 → codesuture-1.0.0}/codesuture/middleware.py +1 -1
  29. codesuture-1.0.0/codesuture/middleware_asgi.py +193 -0
  30. {codesuture-0.7.3 → codesuture-1.0.0}/codesuture/pattern_matcher.py +41 -8
  31. {codesuture-0.7.3 → codesuture-1.0.0}/codesuture/persistence.py +2 -0
  32. {codesuture-0.7.3 → codesuture-1.0.0}/codesuture/rollback.py +23 -1
  33. {codesuture-0.7.3 → codesuture-1.0.0}/codesuture/sandbox.py +1 -1
  34. codesuture-1.0.0/codesuture/shadow.py +229 -0
  35. codesuture-1.0.0/codesuture/suggest.py +304 -0
  36. {codesuture-0.7.3 → codesuture-1.0.0}/codesuture/tracer.py +186 -38
  37. codesuture-1.0.0/codesuture/utils.py +61 -0
  38. codesuture-1.0.0/codesuture.egg-info/PKG-INFO +430 -0
  39. {codesuture-0.7.3 → codesuture-1.0.0}/codesuture.egg-info/SOURCES.txt +35 -2
  40. {codesuture-0.7.3 → codesuture-1.0.0}/codesuture.egg-info/requires.txt +4 -0
  41. {codesuture-0.7.3 → codesuture-1.0.0}/pyproject.toml +9 -2
  42. codesuture-1.0.0/requirements.txt +3 -0
  43. codesuture-1.0.0/tests/test_alerts.py +249 -0
  44. codesuture-1.0.0/tests/test_alerts_hard.py +649 -0
  45. codesuture-1.0.0/tests/test_http_replay.py +103 -0
  46. codesuture-1.0.0/tests/test_incidents.py +247 -0
  47. codesuture-1.0.0/tests/test_incidents_hard.py +601 -0
  48. codesuture-1.0.0/tests/test_lifecycle.py +182 -0
  49. codesuture-1.0.0/tests/test_metrics.py +115 -0
  50. codesuture-1.0.0/tests/test_middleware.py +97 -0
  51. codesuture-1.0.0/tests/test_middleware_asgi.py +249 -0
  52. codesuture-1.0.0/tests/test_negative.py +131 -0
  53. {codesuture-0.7.3 → codesuture-1.0.0}/tests/test_pattern_matcher.py +25 -6
  54. {codesuture-0.7.3 → codesuture-1.0.0}/tests/test_rollback.py +27 -0
  55. codesuture-1.0.0/tests/test_sandbox.py +166 -0
  56. codesuture-1.0.0/tests/test_shadow.py +287 -0
  57. codesuture-1.0.0/tests/test_ship_gate.py +682 -0
  58. codesuture-1.0.0/tests/test_suggestions.py +295 -0
  59. codesuture-1.0.0/tests/test_tracer_integration.py +160 -0
  60. codesuture-0.7.3/.gitignore +0 -53
  61. codesuture-0.7.3/LICENSE +0 -33
  62. codesuture-0.7.3/MANIFEST.in +0 -14
  63. codesuture-0.7.3/PKG-INFO +0 -217
  64. codesuture-0.7.3/README.md +0 -195
  65. codesuture-0.7.3/codesuture/__init__.py +0 -1
  66. codesuture-0.7.3/codesuture/cli.py +0 -130
  67. codesuture-0.7.3/codesuture/shadow.py +0 -20
  68. codesuture-0.7.3/codesuture.egg-info/PKG-INFO +0 -217
  69. codesuture-0.7.3/tests/__init__.py +0 -0
  70. {codesuture-0.7.3 → codesuture-1.0.0}/CHANGELOG.md +0 -0
  71. {codesuture-0.7.3 → codesuture-1.0.0}/codesuture/__main__.py +0 -0
  72. {codesuture-0.7.3 → codesuture-1.0.0}/codesuture/_eval_fix.py +0 -0
  73. {codesuture-0.7.3 → codesuture-1.0.0}/codesuture/code_replacer.py +0 -0
  74. {codesuture-0.7.3 → codesuture-1.0.0}/codesuture/debuggee.py +0 -0
  75. {codesuture-0.7.3 → codesuture-1.0.0}/codesuture/diff_guard.py +0 -0
  76. {codesuture-0.7.3 → codesuture-1.0.0}/codesuture/knowledge.py +0 -0
  77. {codesuture-0.7.3 → codesuture-1.0.0}/codesuture/opcodes.py +0 -0
  78. {codesuture-0.7.3 → codesuture-1.0.0}/codesuture/plugins/__init__.py +0 -0
  79. {codesuture-0.7.3 → codesuture-1.0.0}/codesuture/plugins/autonomous.py +0 -0
  80. {codesuture-0.7.3 → codesuture-1.0.0}/codesuture/rewind.py +0 -0
  81. {codesuture-0.7.3 → codesuture-1.0.0}/codesuture/watcher.py +0 -0
  82. {codesuture-0.7.3 → codesuture-1.0.0}/codesuture.egg-info/dependency_links.txt +0 -0
  83. {codesuture-0.7.3 → codesuture-1.0.0}/codesuture.egg-info/entry_points.txt +0 -0
  84. {codesuture-0.7.3 → codesuture-1.0.0}/codesuture.egg-info/top_level.txt +0 -0
  85. {codesuture-0.7.3 → codesuture-1.0.0}/setup.cfg +0 -0
  86. {codesuture-0.7.3 → codesuture-1.0.0}/setup.py +0 -0
  87. {codesuture-0.7.3 → codesuture-1.0.0}/tests/test_e2e.py +0 -0
  88. {codesuture-0.7.3 → codesuture-1.0.0}/tests/test_guard_synthesizer.py +0 -0
  89. {codesuture-0.7.3 → codesuture-1.0.0}/tests/test_harness.py +0 -0
  90. {codesuture-0.7.3 → codesuture-1.0.0}/tests/test_harness2.py +0 -0
  91. {codesuture-0.7.3 → codesuture-1.0.0}/tests/test_new_guards.py +0 -0
  92. {codesuture-0.7.3 → codesuture-1.0.0}/tests/test_opcodes.py +0 -0
  93. {codesuture-0.7.3 → codesuture-1.0.0}/tests/test_persistence.py +0 -0
  94. {codesuture-0.7.3 → codesuture-1.0.0}/tests/test_thread_safety.py +0 -0
  95. {codesuture-0.7.3 → codesuture-1.0.0}/tests/test_transparency.py +0 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 MUHAMMAD ABUBAKAR
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,18 @@
1
+ include pyproject.toml
2
+ include README.md
3
+ include CHANGELOG.md
4
+ include LICENSE
5
+ include requirements.txt
6
+
7
+ recursive-include codesuture *.py
8
+ recursive-include assets *.png
9
+
10
+ # Exclude dev-only files from pip sdist
11
+ prune stress
12
+ prune .codesuture_store
13
+ prune .codesuture_incidents
14
+ prune .codesuture_alerts
15
+ exclude .gitignore
16
+ exclude ROADMAP.md
17
+ exclude *.debug.py
18
+ exclude *.zip
@@ -0,0 +1,430 @@
1
+ Metadata-Version: 2.4
2
+ Name: codesuture
3
+ Version: 1.0.0
4
+ Summary: Runtime Python bytecode patcher with guard knowledge base, persistence, and self-healing re-execution
5
+ License-Expression: MIT
6
+ Project-URL: Source, https://github.com/codesuture/codesuture
7
+ Keywords: bytecode,runtime,patching,self-healing,debugging,null-safety,resilience
8
+ Classifier: Development Status :: 4 - Beta
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: Topic :: Software Development :: Debuggers
11
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Requires-Python: >=3.11
16
+ Description-Content-Type: text/markdown
17
+ License-File: LICENSE
18
+ Requires-Dist: bytecode>=0.15.1
19
+ Provides-Extra: autonomous
20
+ Requires-Dist: llama-cpp-python; extra == "autonomous"
21
+ Provides-Extra: test
22
+ Requires-Dist: pytest>=7.0; extra == "test"
23
+ Requires-Dist: pytest-asyncio; extra == "test"
24
+ Dynamic: license-file
25
+
26
+ <p align="center">
27
+ <img src="assets/hero.png" alt="CodeSuture" width="100%">
28
+ </p>
29
+
30
+ <h1 align="center">CodeSuture</h1>
31
+
32
+ <p align="center">
33
+ <strong>Self-healing runtime for Python. Catches crashes, patches live bytecode, keeps your server alive.</strong>
34
+ </p>
35
+
36
+ <p align="center">
37
+ <a href="#"><img src="https://img.shields.io/badge/version-1.0.0-0d6efd?style=for-the-badge" alt="Version"></a>
38
+ <a href="#"><img src="https://img.shields.io/badge/python-3.11%2B-10b981?style=for-the-badge" alt="Python"></a>
39
+ <a href="#"><img src="https://img.shields.io/badge/tests-416%20passing-10b981?style=for-the-badge" alt="Tests"></a>
40
+ <a href="#"><img src="https://img.shields.io/badge/license-MIT-6366f1?style=for-the-badge" alt="License"></a>
41
+ </p>
42
+
43
+ <p align="center">
44
+ <code>pip install codesuture</code>
45
+ </p>
46
+
47
+ > ⚠️ **CodeSuture modifies live bytecode at runtime.** Use in production at your own risk. Always verify patches with `codesuture audit` and `codesuture explain` before relying on them.
48
+
49
+ ---
50
+
51
+ ## What is CodeSuture?
52
+
53
+ When a Python program crashes — `AttributeError`, `KeyError`, `ZeroDivisionError`, `IndexError`, `TypeError` — CodeSuture intercepts the exception **at the exact bytecode instruction**, analyzes the crash pattern, injects a deterministic guard into the function's code object **in memory**, and retries execution.
54
+
55
+ No source files are modified. No decorator required. No restart needed.
56
+
57
+ ```bash
58
+ codesuture run your_app.py
59
+ ```
60
+
61
+ ```
62
+ [CodeSuture] Caught AttributeError: 'NoneType' object has no attribute 'bio'
63
+ [CodeSuture] Applying null_guard on 'profile' ...
64
+ [CodeSuture] Patch applied to get_bio().
65
+ [CodeSuture] Active Shield: Native frame rewound for get_bio() successfully.
66
+
67
+ Session summary:
68
+ Patches applied: 1
69
+ ```
70
+
71
+ Run it again — the patch loads from disk before the first call:
72
+
73
+ ```
74
+ [CodeSuture] Already healed: loaded persistent patch for get_bio
75
+ ```
76
+
77
+ ---
78
+
79
+ ## How It Works
80
+
81
+ <p align="center">
82
+ <img src="assets/architecture.png" alt="CodeSuture Architecture" width="90%">
83
+ </p>
84
+
85
+ CodeSuture operates in five stages:
86
+
87
+ | Stage | What happens |
88
+ |-------|-------------|
89
+ | **① Catch** | `sys.settrace()` intercepts exceptions at the exact frame and bytecode offset |
90
+ | **② Analyze** | The pattern matcher disassembles the failing instruction chain and identifies the crashing variable, operation, and crash type |
91
+ | **③ Patch** | The guard synthesizer injects new bytecode into the function's code object. A semantic diff gate rejects patches that modify too much logic |
92
+ | **④ Rewind** | The execution frame is rewound to re-enter the patched function. On HTTP servers, the full transaction is replayed — the client gets a `200` |
93
+ | **⑤ Persist** | The patched code object is serialized to `.codesuture_store/` with SHA-256 integrity checks and TTL metadata |
94
+
95
+ ---
96
+
97
+ ## Guard Types
98
+
99
+ <p align="center">
100
+ <img src="assets/guards.png" alt="Guard Types" width="80%">
101
+ </p>
102
+
103
+ CodeSuture ships with **11 deterministic guard types** — each one targets a specific crash pattern and injects the minimal bytecode fix:
104
+
105
+ | Guard | Crash Type | Example | What It Does |
106
+ |-------|-----------|---------|--------------|
107
+ | `null_guard` | `AttributeError` on `None` | `user.profile.bio` | Inserts `if x is None: x = default` before attribute access |
108
+ | `key_guard` | `KeyError` | `config["timeout"]` | Wraps dict access with `.get(key, default)` |
109
+ | `subscript_guard` | `TypeError` subscripting `None` | `data["key"]` when `data` is `None` | Null-checks the container before subscript |
110
+ | `chain_subscript_guard` | Nested subscript failures | `resp["user"]["name"]["first"]` | Guards the entire chain from the root |
111
+ | `index_guard` | `IndexError` (variable index) | `items[i]` when `i >= len(items)` | Bounds-checks `i` against `len(items)` |
112
+ | `list_bound_guard` | `IndexError` (constant index) | `parts[3]` when `len(parts) < 4` | Checks `len(parts) > 3` before access |
113
+ | `division_guard` | `ZeroDivisionError` | `total / count` when `count` is `0` | Substitutes a safe divisor when variable denominator is zero |
114
+ | `str_coerce_guard` | `TypeError` on string concat | `"age: " + age` when `age` is `int` | Wraps non-str variable with `str()` after assignment |
115
+ | `type_coercion_guard` | `TypeError` on conversion | `int("not_a_number")` | Adds type validation before coercion |
116
+ | `file_guard` | `FileNotFoundError` | `open(path)` | Checks `os.path.exists()` before open |
117
+ | `callable_guard` | `TypeError` calling `None` | `callback()` when `callback` is `None` | Returns `None` for unknown callables |
118
+
119
+ ---
120
+
121
+ ## CLI Reference
122
+
123
+ ### Core Commands
124
+
125
+ ```bash
126
+ # Run a script with live patching
127
+ codesuture run app.py
128
+
129
+ # Run with full diagnostics
130
+ codesuture run app.py --verbose --shadow --retries 5
131
+
132
+ # Preview patches without applying
133
+ codesuture run app.py --dry-run
134
+
135
+ # Watch mode — auto-restart after patches
136
+ codesuture watch server.py --max-restarts 10
137
+ ```
138
+
139
+ ### Inspection & Governance
140
+
141
+ ```bash
142
+ # Show all active patches
143
+ codesuture audit
144
+
145
+ # Plain-language explanation of patches
146
+ codesuture explain
147
+ codesuture explain get_user_profile
148
+
149
+ # View incident log
150
+ codesuture incidents
151
+ codesuture incidents --since 2d
152
+
153
+ # Generate markdown incident report
154
+ codesuture digest
155
+
156
+ # View fix suggestions
157
+ codesuture suggest
158
+
159
+ # Export Prometheus metrics
160
+ codesuture metrics
161
+
162
+ # View patch lifecycle states
163
+ codesuture lifecycle show
164
+ ```
165
+
166
+ ### Rollback & Cleanup
167
+
168
+ ```bash
169
+ # Roll back a specific patch
170
+ codesuture rollback get_user_profile
171
+
172
+ # Preview what would be removed
173
+ codesuture rollback --dry-run
174
+
175
+ # Remove everything — patches, fingerprints, incidents
176
+ codesuture rollback --all
177
+ ```
178
+
179
+ ### Alerts
180
+
181
+ ```bash
182
+ # View unread alerts
183
+ codesuture alerts
184
+
185
+ # Dismiss alerts for a resolved incident
186
+ codesuture alerts dismiss <incident_id>
187
+ ```
188
+
189
+ ---
190
+
191
+ ## HTTP Recovery
192
+
193
+ CodeSuture patches exceptions inside HTTP request handlers. When a handler crashes and a guard is synthesized, CodeSuture patches the function **mid-request** and replays the transaction in-place. The client receives a response instead of a socket close.
194
+
195
+ ```
196
+ [CodeSuture] Caught AttributeError: 'NoneType' object has no attribute 'get_profile'
197
+ [CodeSuture] Applying null_guard on 'get_profile' ...
198
+ [CodeSuture] Patch applied to do_GET().
199
+ [CodeSuture] Transaction replay armed for do_GET().
200
+ [CodeSuture] Transaction replay: retrying patched HTTP handler in-place.
201
+ 127.0.0.1 - - "GET /user-data HTTP/1.1" 200 -
202
+ ```
203
+
204
+ Every patched response carries a transparency header:
205
+
206
+ ```http
207
+ HTTP/1.0 200 OK
208
+ Content-type: application/json
209
+ X-CodeSuture: patched=1; guard=null_guard; target=get_profile
210
+
211
+ {"result": null}
212
+ ```
213
+
214
+ ### Framework Middleware
215
+
216
+ ```python
217
+ # WSGI (Flask, Django, Bottle, etc.)
218
+ from codesuture.middleware import CodeSutureMiddleware
219
+ app = CodeSutureMiddleware(your_wsgi_app)
220
+
221
+ # ASGI (FastAPI, Starlette, etc.)
222
+ from codesuture.middleware_asgi import CodeSutureASGIMiddleware
223
+ app = CodeSutureASGIMiddleware(your_asgi_app)
224
+ ```
225
+
226
+ ---
227
+
228
+ ## Incident Intelligence
229
+
230
+ Every crash CodeSuture intercepts is logged as a structured incident with automatic severity classification:
231
+
232
+ | Severity | When |
233
+ |----------|------|
234
+ | **CRITICAL** | Callable replacement, sensitive modules (auth, payment, billing) |
235
+ | **HIGH** | First occurrence, HTTP mutating methods (POST/PUT/DELETE), chain subscripts |
236
+ | **MEDIUM** | Standard guards (null, key, division, index) after first occurrence |
237
+ | **LOW** | Repeat patterns, file guards, string coercion |
238
+
239
+ ```bash
240
+ $ codesuture incidents
241
+
242
+ Time Severity Function Guard Target Status
243
+ ──────────────────── ────────── ───────────────────────── ──────────────────── ─────────────── ──────────
244
+ 2026-05-26T19:05:55 MEDIUM render_user_card null_guard user patched
245
+ 2026-05-26T19:05:55 HIGH format_weather_report chain_subscript_guard data patched
246
+ 2026-05-26T19:05:56 MEDIUM compute_metrics division_guard success patched
247
+ ```
248
+
249
+ ```bash
250
+ $ codesuture digest
251
+
252
+ # CodeSuture Daily Incident Report — 2026-05-26
253
+
254
+ ## Summary
255
+ - **Total incidents:** 3
256
+ - **CRITICAL:** 0 | **HIGH:** 1 | **MEDIUM:** 2 | **LOW:** 0
257
+ - **Unique crash patterns:** 3
258
+ - **Functions patched:** 3
259
+ ```
260
+
261
+ ---
262
+
263
+ ## Alert System
264
+
265
+ CodeSuture routes incidents to alert channels based on severity:
266
+
267
+ - **File alerts** — Markdown files written to `.codesuture_alerts/`
268
+ - **Webhook alerts** — HTTP POST to your alerting endpoint (Slack, PagerDuty, etc.)
269
+ - **Escalation** — Functions patched 5+ times in 24 hours are auto-escalated
270
+
271
+ ```bash
272
+ $ codesuture alerts
273
+
274
+ CodeSuture — Unread Alerts
275
+
276
+ [HIGH] format_weather_report crashed with KeyError, patched with chain_subscript_guard
277
+ Escalating get_user_display from HIGH to CRITICAL (patched 5 times in 24h)
278
+ ```
279
+
280
+ ---
281
+
282
+ ## Shadow Execution
283
+
284
+ With `--shadow`, CodeSuture runs the original (unpatched) function alongside the patched version and compares results:
285
+
286
+ ```bash
287
+ codesuture run app.py --shadow
288
+ ```
289
+
290
+ | Verdict | Meaning |
291
+ |---------|---------|
292
+ | **JUSTIFIED** | Original crashes, patched succeeds — the patch is necessary |
293
+ | **UNNECESSARY** | Both produce the same result — consider removing the patch |
294
+ | **DIVERGENT** | Results differ — the patch changes behavior, review recommended |
295
+
296
+ Shadow-verified patches get upgraded to **VERIFIED** confidence in fix suggestions.
297
+
298
+ ---
299
+
300
+ ## Fix Suggestions
301
+
302
+ CodeSuture generates concrete source-code fix suggestions for every active patch:
303
+
304
+ ```bash
305
+ $ codesuture suggest
306
+
307
+ Function: render_user_card
308
+ Guard: null_guard on 'profile'
309
+ Confidence: LIKELY
310
+
311
+ --- a/app.py
312
+ +++ b/app.py
313
+ @@ -15,1 +15,1 @@
314
+ - bio = user.profile.bio
315
+ + bio = user.profile.bio if user.profile is not None else ''
316
+ ```
317
+
318
+ Confidence levels:
319
+ - **VERIFIED** — Shadow execution confirmed the fix works
320
+ - **LIKELY** — Deterministic guard with high confidence
321
+ - **EXPERIMENTAL** — Complex guard, review recommended
322
+
323
+ ---
324
+
325
+ ## Lifecycle Management
326
+
327
+ Every patch transitions through a state machine:
328
+
329
+ ```
330
+ DETECTED → PATCHED → PERSISTED → SUGGESTED → VERIFIED → FIXED
331
+ ↓ ↓
332
+ REPLAYED EXPIRED
333
+
334
+ ROLLED_BACK
335
+ ```
336
+
337
+ ```bash
338
+ $ codesuture lifecycle show
339
+
340
+ Function State Age TTL
341
+ get_bio PERSISTED 2d 7d
342
+ compute_ratio VERIFIED 1d 7d
343
+ parse_config EXPIRED 8d 7d ← needs attention
344
+ ```
345
+
346
+ ---
347
+
348
+ ## Prometheus Metrics
349
+
350
+ Export patch metrics in Prometheus text format:
351
+
352
+ ```bash
353
+ $ codesuture metrics
354
+
355
+ # HELP codesuture_incidents_total Total incidents recorded
356
+ # TYPE codesuture_incidents_total counter
357
+ codesuture_incidents_total 20
358
+ codesuture_patches_total{guard_type="null_guard"} 12
359
+ codesuture_patches_total{guard_type="key_guard"} 5
360
+ codesuture_patches_total{guard_type="division_guard"} 3
361
+ ```
362
+
363
+ ---
364
+
365
+ ## Safety & Security
366
+
367
+ | Feature | What it prevents |
368
+ |---------|-----------------|
369
+ | **Semantic diff gate** | Rejects patches that modify too many instructions. The engine never corrupts a complex function to fix a simple crash |
370
+ | **SHA-256 integrity** | Persisted `.code` files are checksummed. Tampered files are refused on load |
371
+ | **Patch validation** | Synthesized bytecode is checked for `LOAD_FAST` references to variables not in `co_varnames`. Invalid patches are rejected |
372
+ | **Original code backup** | Pre-patch code objects are stored in `_ORIGINAL_CODES` for runtime rollback |
373
+ | **Patch TTL** | Every patch carries a time-to-live. Expired patches warn to fix the root cause |
374
+ | **Thread safety** | All shared state protected by locks. Safe under free-threaded Python 3.13+ (no-GIL) |
375
+ | **Caller-aware propagation** | After patching, `gc.get_referrers` updates closures, bound methods, and partials |
376
+ | **Runtime rollback** | `codesuture rollback` removes disk files AND restores original code in the running process |
377
+ | **CPython portability** | Version-aware opcode sets handle 3.11, 3.12, and 3.13+ instruction differences |
378
+
379
+ ---
380
+
381
+ ## Known Limitations
382
+
383
+ | Limitation | Detail |
384
+ |-----------|--------|
385
+ | **Python 3.11+ only** | Depends on CPython bytecode structures introduced in 3.11 |
386
+ | **First crash leaks** | The initial exception propagates to the caller. The patch prevents recurrence on subsequent calls |
387
+ | **Comprehensions** | List/dict/set/generator comprehensions are anonymous nested code objects — CodeSuture logs a warning and skips them |
388
+ | **Semantic bugs** | CodeSuture fixes structural crashes (null access, missing keys, type mismatches). Logic errors that produce wrong results without crashing cannot be detected |
389
+ | **Single-process** | Patches apply per-process. `.codesuture_store/` is shared on disk for cross-restart persistence |
390
+ | **Async (experimental)** | Standard `async def` functions are patched. Async generators and deep `await` chains may not be handled correctly |
391
+
392
+ ---
393
+
394
+ ## What CodeSuture Is Not
395
+
396
+ **Not a logger.** It doesn't record exceptions and move on. It patches the function and retries.
397
+
398
+ **Not a static analyzer.** It operates at runtime on live bytecode, not on source files.
399
+
400
+ **Not autonomous by default.** All patches are deterministic rule-based guards. An opt-in `--autonomous` flag exists for experimental LLM-powered suggestions, but it never auto-applies.
401
+
402
+ **Not a replacement for fixing bugs.** CodeSuture is a runtime safety net. The `suggest` command tells you exactly what source code to change. The `lifecycle` system tracks patch age. Expired patches mean you should have fixed the root cause by now.
403
+
404
+ ---
405
+
406
+ ## Installation
407
+
408
+ ```bash
409
+ pip install codesuture
410
+ ```
411
+
412
+ Requires **Python 3.11+** and the [`bytecode`](https://pypi.org/project/bytecode/) library (installed automatically).
413
+
414
+ For experimental LLM-powered autonomous mode:
415
+
416
+ ```bash
417
+ pip install "codesuture[autonomous]"
418
+ ```
419
+
420
+ ---
421
+
422
+ ## License
423
+
424
+ MIT. See [LICENSE](LICENSE) for details.
425
+
426
+ ---
427
+
428
+ <p align="center">
429
+ <sub>Built with obsession, not sleep. If CodeSuture saved your server at 3 AM, consider giving it a ⭐.</sub>
430
+ </p>