aether-lang-runtime 0.1.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 (42) hide show
  1. aether_lang_runtime-0.1.0/.gitignore +26 -0
  2. aether_lang_runtime-0.1.0/PKG-INFO +457 -0
  3. aether_lang_runtime-0.1.0/README.md +427 -0
  4. aether_lang_runtime-0.1.0/ai_runtime/__init__.py +31 -0
  5. aether_lang_runtime-0.1.0/ai_runtime/_types.py +66 -0
  6. aether_lang_runtime-0.1.0/ai_runtime/ast/engine.py +301 -0
  7. aether_lang_runtime-0.1.0/ai_runtime/cli.py +208 -0
  8. aether_lang_runtime-0.1.0/ai_runtime/observability/__init__.py +14 -0
  9. aether_lang_runtime-0.1.0/ai_runtime/observability/audit_log.py +209 -0
  10. aether_lang_runtime-0.1.0/ai_runtime/observability/diff.py +276 -0
  11. aether_lang_runtime-0.1.0/ai_runtime/observability/events.py +69 -0
  12. aether_lang_runtime-0.1.0/ai_runtime/orchestrator.py +363 -0
  13. aether_lang_runtime-0.1.0/ai_runtime/patch_engine.py +272 -0
  14. aether_lang_runtime-0.1.0/ai_runtime/sandbox.py +326 -0
  15. aether_lang_runtime-0.1.0/ai_runtime/sandbox_runner.py +136 -0
  16. aether_lang_runtime-0.1.0/ai_runtime/sandbox_t1.py +317 -0
  17. aether_lang_runtime-0.1.0/ai_runtime/sandbox_t2.py +227 -0
  18. aether_lang_runtime-0.1.0/ai_runtime/sandbox_t3.py +392 -0
  19. aether_lang_runtime-0.1.0/ai_runtime/snapshot/__init__.py +12 -0
  20. aether_lang_runtime-0.1.0/ai_runtime/snapshot/gitignore.py +200 -0
  21. aether_lang_runtime-0.1.0/ai_runtime/snapshot/lock.py +138 -0
  22. aether_lang_runtime-0.1.0/ai_runtime/snapshot/store.py +441 -0
  23. aether_lang_runtime-0.1.0/ai_runtime/validation/__init__.py +25 -0
  24. aether_lang_runtime-0.1.0/ai_runtime/validation/ae_bridge.py +363 -0
  25. aether_lang_runtime-0.1.0/ai_runtime/validation/patch_schema.json +231 -0
  26. aether_lang_runtime-0.1.0/ai_runtime/validation/rules.py +209 -0
  27. aether_lang_runtime-0.1.0/ai_runtime/validation/schema.py +111 -0
  28. aether_lang_runtime-0.1.0/pyproject.toml +61 -0
  29. aether_lang_runtime-0.1.0/tests/test_agent_skill_examples.py +20 -0
  30. aether_lang_runtime-0.1.0/tests/test_ast_engine.py +234 -0
  31. aether_lang_runtime-0.1.0/tests/test_cli_agent_commands.py +77 -0
  32. aether_lang_runtime-0.1.0/tests/test_ffi_fuzz.py +312 -0
  33. aether_lang_runtime-0.1.0/tests/test_observability.py +108 -0
  34. aether_lang_runtime-0.1.0/tests/test_orchestrator.py +222 -0
  35. aether_lang_runtime-0.1.0/tests/test_rollback_fault.py +289 -0
  36. aether_lang_runtime-0.1.0/tests/test_sandbox.py +257 -0
  37. aether_lang_runtime-0.1.0/tests/test_sandbox_t2.py +65 -0
  38. aether_lang_runtime-0.1.0/tests/test_sandbox_t3_windows.py +50 -0
  39. aether_lang_runtime-0.1.0/tests/test_semantic_gate.py +330 -0
  40. aether_lang_runtime-0.1.0/tests/test_snapshot.py +329 -0
  41. aether_lang_runtime-0.1.0/tests/test_validation.py +323 -0
  42. aether_lang_runtime-0.1.0/uv.lock +1195 -0
@@ -0,0 +1,26 @@
1
+ # Python
2
+ __pycache__/
3
+ *.pyc
4
+ *.pyo
5
+ *.pyd
6
+ .mypy_cache/
7
+ .ruff_cache/
8
+ .pytest_cache/
9
+ *.egg-info/
10
+ dist/
11
+ build/
12
+ .venv/
13
+ venv/
14
+ env/
15
+
16
+ # AI-Safe runtime store (generated at runtime, not source)
17
+ .ai_runtime/
18
+ .benchmarks/
19
+
20
+ # Coverage
21
+ .coverage
22
+ htmlcov/
23
+
24
+ # OS
25
+ .DS_Store
26
+ Thumbs.db
@@ -0,0 +1,457 @@
1
+ Metadata-Version: 2.5
2
+ Name: aether-lang-runtime
3
+ Version: 0.1.0
4
+ Summary: AI-Safe Execution Infrastructure: structured, sandboxed, reversible AI code modification
5
+ License: MIT
6
+ Keywords: agents,ai,execution,patch,safe,sandbox
7
+ Classifier: Development Status :: 3 - Alpha
8
+ Classifier: Intended Audience :: Developers
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.10
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Topic :: Security
15
+ Classifier: Topic :: Software Development :: Libraries
16
+ Requires-Python: >=3.10
17
+ Requires-Dist: jsonschema>=4.22
18
+ Requires-Dist: libcst>=1.1.0
19
+ Requires-Dist: pathspec>=0.12
20
+ Requires-Dist: zstandard>=0.23; sys_platform != 'win32'
21
+ Provides-Extra: dev
22
+ Requires-Dist: mypy>=1.10; extra == 'dev'
23
+ Requires-Dist: pytest-benchmark>=4.0; extra == 'dev'
24
+ Requires-Dist: pytest-cov>=5.0; extra == 'dev'
25
+ Requires-Dist: pytest>=8.0; extra == 'dev'
26
+ Requires-Dist: ruff>=0.5; extra == 'dev'
27
+ Provides-Extra: wasm
28
+ Requires-Dist: wasmtime>=23.0; extra == 'wasm'
29
+ Description-Content-Type: text/markdown
30
+
31
+ # AI-Safe Execution Infrastructure
32
+
33
+ > **A structured, sandboxed, and reversible execution layer for AI-driven code modification.**
34
+
35
+ [![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)
36
+ [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
37
+ [![Tests](https://img.shields.io/badge/tests-94%20passed-brightgreen.svg)](#testing)
38
+ [![Platform](https://img.shields.io/badge/platform-Windows%20%7C%20Linux%20%7C%20macOS-lightgrey.svg)](#requirements)
39
+
40
+ ---
41
+
42
+ ## The Problem
43
+
44
+ When AI agents generate code and apply it directly to a codebase, several fundamental failure modes emerge:
45
+
46
+ | Failure | Impact |
47
+ |:--------|:-------|
48
+ | **Syntax errors** | File is broken, app crashes |
49
+ | **Semantic errors** | Logic is wrong, tests fail silently |
50
+ | **Uncontrolled execution** | Changes applied directly against live state |
51
+ | **No rollback path** | Recovery requires manual `git reset` or worse |
52
+ | **Ambiguous intent** | Agent emits free-form diffs, no structured contract |
53
+
54
+ `aether-lang-runtime` reframes the problem: instead of agents generating raw source code, they emit **structured patch instructions** — a typed JSON contract — that the runtime validates, sandboxes, and commits or rolls back automatically.
55
+
56
+ ---
57
+
58
+ ## Architecture
59
+
60
+ ```
61
+ ┌─────────────────────────────────────────────────────────────────┐
62
+ │ AI Agent │
63
+ │ (LLM, Copilot, AutoGPT, etc.) │
64
+ └────────────────────────┬────────────────────────────────────────┘
65
+ │ Structured Patch (JSON)
66
+
67
+ ┌─────────────────────────────────────────────────────────────────┐
68
+ │ Validation Layer │
69
+ │ │
70
+ │ Gate 1 ──── JSON Schema (Draft 2020-12) │
71
+ │ • Action type enforcement │
72
+ │ • UUID patch_id required │
73
+ │ • Payload size ceiling (64 KB) │
74
+ │ • Timeout bounds [100ms – 30s] │
75
+ │ │
76
+ │ Gate 2 ──── Allow-list & Security Rules │
77
+ │ • (action, operation) allow-list │
78
+ │ • No absolute paths / path traversal │
79
+ │ • No os.system / subprocess / eval in payload │
80
+ │ • run_script requires explicit trust elevation │
81
+ └────────────────────────┬────────────────────────────────────────┘
82
+ │ Valid patch only
83
+
84
+ ┌─────────────────────────────────────────────────────────────────┐
85
+ │ Snapshot System │
86
+ │ │
87
+ │ • Captures project state → .tar.gz archive │
88
+ │ • .gitignore + .ai_runtimeignore aware │
89
+ │ • Always skips: node_modules / venv / __pycache__ / .git │
90
+ │ • SQLite WAL index (concurrent-reader safe) │
91
+ │ • Cross-platform write lock (fcntl / msvcrt) │
92
+ │ • Atomic rename: no partial archives ever on disk │
93
+ └────────────────────────┬────────────────────────────────────────┘
94
+
95
+
96
+ ┌─────────────────────────────────────────────────────────────────┐
97
+ │ Sandbox Execution │
98
+ │ │
99
+ │ Tier 1 ── Cranelift JIT (zero-syscall, v1.2+) │
100
+ │ Tier 2 ── Wasmtime/WASM (hardware boundary, v1.1+) │
101
+ │ Tier 3 ── Subprocess (OS process isolation, v1.0 ✅) │
102
+ │ • Windows: Win32 Job Objects (memory limit) │
103
+ │ • Linux: resource.setrlimit (RLIMIT_AS + CPU) │
104
+ │ • Timeout enforced via communicate(timeout=) │
105
+ │ • CREATE_NEW_PROCESS_GROUP (Windows signal safety) │
106
+ │ • setsid() + preexec_fn (Unix process group) │
107
+ └────────────────────────┬────────────────────────────────────────┘
108
+
109
+ ┌──────────┴──────────┐
110
+ │ │
111
+ Success Failure
112
+ │ │
113
+ ▼ ▼
114
+ ┌──────────┐ ┌──────────────┐
115
+ │ Commit │ │ Rollback │
116
+ │ snapshot │ │ from archive │
117
+ └──────────┘ └──────────────┘
118
+ ```
119
+
120
+ ---
121
+
122
+ ## Project Layout
123
+
124
+ ```
125
+ aether-lang/
126
+ ├── sdk/
127
+ │ └── python/
128
+ │ ├── ai_runtime/
129
+ │ │ ├── __init__.py # Public API: PatchEngine, Sandbox, etc.
130
+ │ │ ├── _types.py # Shared dataclasses (ExecutionResult, SnapshotHandle)
131
+ │ │ ├── patch_engine.py # PatchEngine — validate() + apply() orchestrator
132
+ │ │ ├── sandbox.py # Sandbox — tier-dispatching execution environment
133
+ │ │ ├── sandbox_t3.py # T3 subprocess backend (Windows + Unix)
134
+ │ │ ├── sandbox_runner.py # Worker script run inside child process
135
+ │ │ ├── validation/
136
+ │ │ │ ├── patch_schema.json # JSON Schema Draft 2020-12 contract
137
+ │ │ │ ├── schema.py # Gate 1: schema validator
138
+ │ │ │ └── rules.py # Gate 2: allow-list + security rules
139
+ │ │ └── snapshot/
140
+ │ │ ├── __init__.py
141
+ │ │ ├── store.py # SnapshotStore — capture/restore/commit/prune
142
+ │ │ ├── gitignore.py # .gitignore-aware file collector
143
+ │ │ └── lock.py # Cross-platform advisory file lock
144
+ │ └── tests/
145
+ │ ├── test_validation.py # Phase 1: 34 tests
146
+ │ ├── test_sandbox.py # Phase 2: 26 tests (cross-platform)
147
+ │ ├── test_sandbox_t3_windows.py # Phase 2: 3 tests (Windows-only)
148
+ │ └── test_snapshot.py # Phase 3: 31 tests
149
+ ├── architecture doc/
150
+ │ └── AI-Safe-Execution-Infrastructure-Documentation.md
151
+ └── crates/ # Legacy Aether language compiler (Cranelift/Rust)
152
+ ```
153
+
154
+ ---
155
+
156
+ ## Quick Start
157
+
158
+ ### Install
159
+
160
+ ```bash
161
+ pip install aether-lang-runtime
162
+ ```
163
+
164
+ ### Basic usage
165
+
166
+ ```python
167
+ import uuid
168
+ from ai_runtime import PatchEngine
169
+
170
+ engine = PatchEngine()
171
+
172
+ patch = {
173
+ "schema_version": "1.0",
174
+ "patch_id": str(uuid.uuid4()), # must be valid UUID v4
175
+ "action": "modify_function",
176
+ "target": {
177
+ "file": "src/app.py", # relative path only
178
+ "symbol": "calculate_total",
179
+ "symbol_type": "function",
180
+ },
181
+ "changes": {
182
+ "operation": "replace_body",
183
+ "payload": " return sum(items)",
184
+ },
185
+ }
186
+
187
+ report = engine.validate(patch)
188
+ if report.ok:
189
+ engine.apply(patch)
190
+ print(f"✅ Applied in {report.elapsed_ms:.1f}ms")
191
+ else:
192
+ print(f"❌ Rejected: {report.first_error}")
193
+ ```
194
+
195
+ ### Agent CLI
196
+
197
+ After installation, agents can use Aether without writing Python glue:
198
+
199
+ ```bash
200
+ aether validate patch.json
201
+ aether apply patch.json
202
+ aether rollback <snapshot-id>
203
+ ```
204
+
205
+ `aether apply` runs validation through `PatchOrchestrator`, captures a snapshot,
206
+ applies the patch, and rolls back if application fails. `ae-safe` is kept as a
207
+ backwards-compatible alias for the same CLI.
208
+
209
+ ### With snapshot + auto-rollback
210
+
211
+ ```python
212
+ from ai_runtime import PatchEngine, Sandbox
213
+
214
+ sandbox = Sandbox(project_root=".")
215
+ engine = PatchEngine(sandbox=sandbox)
216
+
217
+ # Capture state before any change
218
+ handle = sandbox.snapshot(patch_id=patch["patch_id"])
219
+
220
+ report = engine.validate(patch)
221
+ if report.ok:
222
+ result = engine.apply(patch)
223
+ if result and result.failed:
224
+ # Execution failed — restore immediately
225
+ sandbox.restore(handle)
226
+ print(f"⚠️ Rolled back: {result.error}")
227
+ else:
228
+ sandbox.commit_snapshot(handle)
229
+ print("✅ Committed")
230
+ else:
231
+ print(f"❌ Rejected at gate {report.first_error}")
232
+ ```
233
+
234
+ ### Execute a sandboxed script
235
+
236
+ ```python
237
+ from ai_runtime import Sandbox
238
+
239
+ with Sandbox(project_root=".") as sb:
240
+ result = sb.execute(
241
+ payload="print('hello from sandbox')",
242
+ timeout_ms=5000,
243
+ memory_limit_mb=128,
244
+ )
245
+
246
+ print(result.stdout) # "hello from sandbox"
247
+ print(result.tier) # "t3_subprocess"
248
+ print(result.succeeded) # True
249
+ ```
250
+
251
+ ---
252
+
253
+ ## Patch Schema
254
+
255
+ Every patch must be a JSON object conforming to [patch_schema.json](ai_runtime/validation/patch_schema.json) (JSON Schema Draft 2020-12).
256
+
257
+ ### Required fields
258
+
259
+ | Field | Type | Description |
260
+ |:------|:-----|:------------|
261
+ | `schema_version` | `"1.0"` | Schema version — must be exactly `"1.0"` |
262
+ | `patch_id` | UUID v4 string | Unique identifier for idempotency tracking |
263
+ | `action` | enum | One of the 7 supported actions below |
264
+ | `target.file` | string | **Relative** path to the target file |
265
+ | `changes.operation` | string | Operation type (must be in allow-list for action) |
266
+ | `changes.payload` | string | Code content, max 64 KB |
267
+
268
+ ### Supported actions
269
+
270
+ | Action | Operations | Description |
271
+ |:-------|:-----------|:------------|
272
+ | `modify_function` | `replace_body`, `insert_before`, `insert_after`, `update_logic` | Modify an existing function |
273
+ | `add_function` | `replace_body` | Insert a new function |
274
+ | `remove_function` | `replace_body` | Delete a function |
275
+ | `modify_class` | `replace_body`, `insert_before`, `insert_after` | Modify a class |
276
+ | `update_import` | `add_import`, `remove_import` | Add or remove imports |
277
+ | `replace_block` | `context_replace` | Context-based block replacement |
278
+ | `run_script` | `run` | Execute a script (requires `trust_level='elevated'`) |
279
+
280
+ ### Optional fields
281
+
282
+ ```json
283
+ {
284
+ "constraints": {
285
+ "timeout_ms": 5000,
286
+ "memory_limit_mb": 128,
287
+ "allow_network": false,
288
+ "allow_filesystem": false
289
+ },
290
+ "metadata": {
291
+ "generated_by": "my-agent-v1",
292
+ "model": "gemini-2.0-flash",
293
+ "confidence": 0.95
294
+ }
295
+ }
296
+ ```
297
+
298
+ ---
299
+
300
+ ## Security Model
301
+
302
+ ### Two-gate validation
303
+
304
+ ```
305
+ Patch JSON
306
+
307
+
308
+ Gate 1: JSON Schema ─── rejects malformed structure
309
+
310
+ ▼ (valid)
311
+ Gate 2: Security Rules
312
+ ├── Operation allow-list ────── unknown (action, operation) pairs rejected
313
+ ├── Path safety ─────────────── absolute paths, ../ traversal blocked
314
+ ├── Payload patterns ────────── os.system / subprocess / eval blocked
315
+ └── Trust elevation ─────────── run_script requires explicit elevated trust
316
+
317
+ ▼ (valid)
318
+ Execution
319
+ ```
320
+
321
+ ### What is NOT protected by this layer
322
+
323
+ - **AI model hallucination**: The runtime validates structure and security, not semantic correctness. A syntactically valid patch can still produce wrong program behaviour.
324
+ - **Supply chain attacks**: Malicious packages in the project's dependencies are not audited.
325
+ - **Persistent rootkits**: A sufficiently clever payload could attempt to escape the T3 subprocess sandbox. T1 (Cranelift) and T2 (WASM) are the hardened tiers for untrusted code.
326
+
327
+ ---
328
+
329
+ ## Sandbox Tiers
330
+
331
+ | Tier | Technology | Memory Limit | Syscall Restriction | Status |
332
+ |:-----|:-----------|:-------------|:--------------------|:-------|
333
+ | **T3** | OS subprocess | Win32 Job Objects / `RLIMIT_AS` | None (process boundary only) | ✅ v1.0 |
334
+ | **T2** | Wasmtime/WASI | WASM linear memory | WASI capabilities | 🔜 v1.1 |
335
+ | **T1** | Cranelift JIT | Custom memory allocator | Zero syscall surface | 🔜 v1.2 |
336
+
337
+ Tier selection is automatic (`preferred_tier="auto"`). T3 is always available; T1/T2 are used when their respective runtimes are detected.
338
+
339
+ ---
340
+
341
+ ## Snapshot System
342
+
343
+ ### Storage layout
344
+
345
+ ```
346
+ <project_root>/
347
+ └── .ai_runtime/
348
+ ├── snapshot.lock ← Advisory write lock (fcntl / msvcrt)
349
+ ├── snapshots.db ← SQLite index (WAL mode)
350
+ └── snapshots/
351
+ ├── <uuid>.tar.gz ← Compressed project archive
352
+ └── ...
353
+ ```
354
+
355
+ ### What gets snapshotted
356
+
357
+ The file collector applies a layered exclusion strategy:
358
+
359
+ ```
360
+ All files in project_root
361
+
362
+ ▼ Tier 1: O(1) frozenset fast-skip
363
+ │ (node_modules, .git, venv, __pycache__, dist, target, ...)
364
+
365
+ ▼ Tier 2: pathspec regex
366
+ │ (*.pyc, *.egg-info/, *.so, ...)
367
+
368
+ ▼ Tier 3: .gitignore patterns
369
+
370
+ ▼ Tier 4: .ai_runtimeignore patterns
371
+
372
+ ▼ Tier 5: Size ceiling (> 5 MB per file → skip)
373
+
374
+
375
+ Source files to archive
376
+ ```
377
+
378
+ ### Snapshot lifecycle
379
+
380
+ ```
381
+ capture("patch-123") status = 'pending'
382
+
383
+ ├── patch applied OK ──▶ commit(handle) status = 'committed'
384
+
385
+ └── execution failed ──▶ restore(handle) status = 'rolled_back'
386
+
387
+ prune(keep=10) ──▶ deletes oldest committed/rolled_back archives
388
+ ```
389
+
390
+ ### Concurrency
391
+
392
+ Multiple agents can operate on the same project simultaneously:
393
+ - `validate()` — fully parallel (read-only, no locking)
394
+ - `capture()` / `restore()` — serialized via advisory write lock per project root
395
+ - SQLite WAL mode — concurrent readers never block during write
396
+
397
+ ---
398
+
399
+ ## Performance SLOs
400
+
401
+ | Operation | Target | Measured (this machine) |
402
+ |:----------|:-------|:------------------------|
403
+ | `validate()` | < 20 ms | **0.12 ms** |
404
+ | `capture()` (< 50 MB project) | < 100 ms | passes ✅ |
405
+ | `restore()` | < 500 ms | passes ✅ |
406
+ | T3 sandbox overhead | < 500 ms | < 200 ms |
407
+ | T3 timeout enforcement | within 2× budget | ✅ |
408
+
409
+ ---
410
+
411
+ ## Testing
412
+
413
+ ```bash
414
+ # Install with dev dependencies
415
+ pip install -e ".[dev]"
416
+
417
+ # Run full suite
418
+ pytest tests/ -v
419
+
420
+ # Phase-by-phase
421
+ pytest tests/test_validation.py # Phase 1 — 34 tests
422
+ pytest tests/test_sandbox.py # Phase 2 — 26 tests
423
+ pytest tests/test_snapshot.py # Phase 3 — 31 tests
424
+ pytest tests/test_sandbox_t3_windows.py # Windows-only — 3 tests
425
+ ```
426
+
427
+ Current suite: **94 tests, 94 passed** (Python 3.14 / Windows 11)
428
+
429
+ ---
430
+
431
+ ## Roadmap
432
+
433
+ | Phase | Status | Description |
434
+ |:------|:-------|:------------|
435
+ | 1 — Validation Layer | ✅ Done | JSON Schema Gate + security rule allow-list |
436
+ | 2 — Sandbox (T3) | ✅ Done | Subprocess isolation, Windows Job Objects, Unix rlimit |
437
+ | 3 — Snapshot System | ✅ Done | `.tar.gz` archives, SQLite WAL, gitignore-aware, cross-platform locks |
438
+ | 4 — Observability | ✅ Done | Structured diffs, audit log, `aether status` CLI |
439
+ | 5 — AST Apply Engine | 🔄 Next | Real `modify_function` / `add_function` via `ast` + `libcst` |
440
+ | 6 — Node.js SDK | 🔜 Planned | `sdk/node/` TypeScript port |
441
+ | 7 — T2 Sandbox (WASM) | 🔜 Planned | Wasmtime WASI integration |
442
+ | 8 — T1 Sandbox (JIT) | 🔜 Planned | Cranelift FFI from existing `crates/ae-codegen` |
443
+
444
+ ---
445
+
446
+ ## Requirements
447
+
448
+ - Python ≥ 3.11
449
+ - `jsonschema >= 4.22`
450
+ - `pathspec >= 0.12`
451
+ - No Docker, no external daemons, no root required
452
+
453
+ ---
454
+
455
+ ## License
456
+
457
+ MIT — see [LICENSE](LICENSE).