lean-runtime 0.6.0__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 (115) hide show
  1. lean_runtime-1.0.0/CHANGELOG.md +96 -0
  2. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/MANIFEST.in +1 -0
  3. lean_runtime-1.0.0/PKG-INFO +175 -0
  4. lean_runtime-1.0.0/README.md +140 -0
  5. lean_runtime-1.0.0/docs/bundles.md +222 -0
  6. lean_runtime-1.0.0/docs/case-study-v1.md +47 -0
  7. lean_runtime-1.0.0/docs/cli.md +121 -0
  8. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/docs/environments.md +8 -2
  9. lean_runtime-1.0.0/docs/getting-started.md +103 -0
  10. lean_runtime-1.0.0/docs/index.md +39 -0
  11. lean_runtime-1.0.0/docs/local-projects.md +58 -0
  12. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/docs/python-api.md +81 -7
  13. lean_runtime-1.0.0/docs/standalone-files.md +52 -0
  14. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/docs/trust-and-limitations.md +15 -3
  15. lean_runtime-1.0.0/docs/v1-precision.md +109 -0
  16. lean_runtime-1.0.0/lean_runtime/__init__.py +138 -0
  17. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/lean_runtime/backends.py +21 -10
  18. lean_runtime-1.0.0/lean_runtime/bundles.py +652 -0
  19. lean_runtime-1.0.0/lean_runtime/cli.py +562 -0
  20. lean_runtime-1.0.0/lean_runtime/decisions.py +24 -0
  21. lean_runtime-1.0.0/lean_runtime/diffing.py +116 -0
  22. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/lean_runtime/environments.py +32 -3
  23. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/lean_runtime/errors.py +24 -0
  24. lean_runtime-1.0.0/lean_runtime/facade.py +206 -0
  25. lean_runtime-1.0.0/lean_runtime/frontmatter.py +75 -0
  26. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/lean_runtime/locking.py +13 -1
  27. lean_runtime-1.0.0/lean_runtime/matrix.py +162 -0
  28. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/lean_runtime/models.py +74 -0
  29. lean_runtime-1.0.0/lean_runtime/oci.py +668 -0
  30. lean_runtime-1.0.0/lean_runtime/profiling.py +70 -0
  31. lean_runtime-1.0.0/lean_runtime/projects.py +213 -0
  32. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/lean_runtime/references.py +51 -8
  33. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/lean_runtime/resolver.py +56 -32
  34. lean_runtime-1.0.0/lean_runtime/run_cli.py +233 -0
  35. lean_runtime-1.0.0/lean_runtime/runtime.py +919 -0
  36. lean_runtime-1.0.0/lean_runtime/schema_resources.py +31 -0
  37. lean_runtime-1.0.0/lean_runtime/signatures.py +137 -0
  38. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/lean_runtime/store.py +147 -7
  39. lean_runtime-1.0.0/lean_runtime/timings.py +17 -0
  40. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/lean_runtime/toolchains.py +15 -9
  41. lean_runtime-1.0.0/lean_runtime/verification.py +261 -0
  42. lean_runtime-1.0.0/lean_runtime/wire.py +74 -0
  43. lean_runtime-1.0.0/lean_runtime.egg-info/PKG-INFO +175 -0
  44. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/lean_runtime.egg-info/SOURCES.txt +41 -1
  45. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/lean_runtime.egg-info/entry_points.txt +1 -0
  46. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/lean_runtime.egg-info/requires.txt +1 -0
  47. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/mkdocs.yml +5 -0
  48. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/pyproject.toml +8 -4
  49. lean_runtime-1.0.0/schemas/diff-v1.schema.json +50 -0
  50. lean_runtime-1.0.0/schemas/execution-v1.schema.json +132 -0
  51. lean_runtime-1.0.0/schemas/gc-v1.schema.json +47 -0
  52. lean_runtime-1.0.0/schemas/inspect-v1.schema.json +79 -0
  53. lean_runtime-1.0.0/schemas/matrix-v1.schema.json +34 -0
  54. lean_runtime-1.0.0/schemas/profile-v1.schema.json +38 -0
  55. lean_runtime-1.0.0/schemas/verify-v1.schema.json +43 -0
  56. lean_runtime-1.0.0/scripts/run_v1_case_study.py +162 -0
  57. lean_runtime-1.0.0/scripts/smoke_wheel.py +66 -0
  58. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/tests/test_backend.py +32 -0
  59. lean_runtime-1.0.0/tests/test_bundles.py +355 -0
  60. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/tests/test_cli.py +34 -1
  61. lean_runtime-1.0.0/tests/test_environment_integration.py +371 -0
  62. lean_runtime-1.0.0/tests/test_facade.py +111 -0
  63. lean_runtime-1.0.0/tests/test_frontmatter.py +60 -0
  64. lean_runtime-1.0.0/tests/test_prebuilt_policy.py +98 -0
  65. lean_runtime-1.0.0/tests/test_projects.py +162 -0
  66. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/tests/test_references.py +14 -0
  67. lean_runtime-1.0.0/tests/test_run_cli.py +122 -0
  68. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/tests/test_runtime.py +21 -2
  69. lean_runtime-1.0.0/tests/test_schema_resources.py +26 -0
  70. lean_runtime-1.0.0/tests/test_schemas.py +128 -0
  71. lean_runtime-1.0.0/tests/test_signatures.py +79 -0
  72. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/tests/test_store.py +37 -1
  73. lean_runtime-1.0.0/tests/test_v1_precision.py +232 -0
  74. lean_runtime-1.0.0/tests/test_verification_inventory.py +18 -0
  75. lean_runtime-0.6.0/CHANGELOG.md +0 -49
  76. lean_runtime-0.6.0/PKG-INFO +0 -332
  77. lean_runtime-0.6.0/README.md +0 -298
  78. lean_runtime-0.6.0/docs/cli.md +0 -72
  79. lean_runtime-0.6.0/docs/getting-started.md +0 -108
  80. lean_runtime-0.6.0/docs/index.md +0 -38
  81. lean_runtime-0.6.0/lean_runtime/__init__.py +0 -67
  82. lean_runtime-0.6.0/lean_runtime/cli.py +0 -254
  83. lean_runtime-0.6.0/lean_runtime/runtime.py +0 -430
  84. lean_runtime-0.6.0/lean_runtime.egg-info/PKG-INFO +0 -332
  85. lean_runtime-0.6.0/tests/test_environment_integration.py +0 -181
  86. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/LICENSE +0 -0
  87. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/compatibility/README.md +0 -0
  88. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/compatibility/mathlib-4.32.2.json +0 -0
  89. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/compatibility/mathlib-4.32.2.toml +0 -0
  90. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/docs/architecture.md +0 -0
  91. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/docs/captures.md +0 -0
  92. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/docs/development.md +0 -0
  93. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/examples/mathlib.toml +0 -0
  94. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/lean_runtime/__main__.py +0 -0
  95. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/lean_runtime/diagnostics.py +0 -0
  96. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/lean_runtime/events.py +0 -0
  97. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/lean_runtime/health.py +0 -0
  98. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/lean_runtime/lake.py +0 -0
  99. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/lean_runtime/lockfiles.py +0 -0
  100. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/lean_runtime/policies.py +0 -0
  101. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/lean_runtime/py.typed +0 -0
  102. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/lean_runtime/serialization.py +0 -0
  103. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/lean_runtime/specs.py +0 -0
  104. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/lean_runtime.egg-info/dependency_links.txt +0 -0
  105. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/lean_runtime.egg-info/top_level.txt +0 -0
  106. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/scripts/run_compatibility.py +0 -0
  107. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/setup.cfg +0 -0
  108. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/tests/conftest.py +0 -0
  109. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/tests/test_diagnostics.py +0 -0
  110. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/tests/test_events_health.py +0 -0
  111. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/tests/test_interactive.py +0 -0
  112. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/tests/test_lockfiles.py +0 -0
  113. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/tests/test_multifile.py +0 -0
  114. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/tests/test_specs.py +0 -0
  115. {lean_runtime-0.6.0 → lean_runtime-1.0.0}/tests/test_toolchains.py +0 -0
@@ -0,0 +1,96 @@
1
+ # Changelog
2
+
3
+ ## 1.0.0
4
+
5
+ Lean Runtime v1 establishes the concise `lean-run` and `lean.setup()` workflows while making
6
+ exact environments independently verifiable, explainable, measurable, and portable.
7
+
8
+ ### Breaking changes
9
+
10
+ - Remove `lean-runtime audit`, `Runtime.audit()`, `AuditReport`, and `ArtifactInventory`;
11
+ `verify` is the sole trust surface and `verify --rebuild` performs independent rebuild checks.
12
+ - Close and version the seven public CLI JSON schemas. Execution payloads now include stable
13
+ phase timings, while `inspect` and `gc` use one canonical data shape each.
14
+ - Remove transitional compatibility surfaces introduced before v1; callers should use the
15
+ top-level façade, `Runtime`, and the documented v1 result types directly.
16
+
17
+ ### Release capabilities
18
+
19
+ - Add lazy `setup`, `check`, `check_file`, and `replay` Python façade functions.
20
+ - Add `lean-run` with strict TOML frontmatter, automatic local-project discovery,
21
+ exact lock input/output, concise progress, and structured JSON output.
22
+ - Add exact `mathlib@REVISION`, `leancert@REVISION`, and
23
+ `owner/repository@REVISION` package references without permitting floating aliases.
24
+ - Add `ExecutionResult.raise_for_error()` and structured `LeanCheckError` failures.
25
+ - Rewrite the README around the front-facing workflow and expand the standalone
26
+ file, CLI, Python, and routing documentation.
27
+ - Discover pinned local Lake projects from contained Lean files and expose a
28
+ distinct mutable `ProjectEnvironment` API.
29
+ - Preserve project-relative file checks and record content, configuration,
30
+ manifest, and Git project provenance without claiming an environment identity.
31
+ - Add transparent OCI prebuilt-cache lookup with authenticated registry pulls,
32
+ disk-backed blob reuse, strict fallback policy, and explicit `pull` support.
33
+ - Add deterministic OCI publishing through `build-and-push`, with blobs and the
34
+ platform manifest committed before the lock-level index tag.
35
+ - Stream bundle layers and OCI archives through temporary files instead of
36
+ materializing multi-gigabyte package layers in memory.
37
+ - Add deterministic OCI image-layout export and verified, atomic environment import.
38
+ - Verify bundle digests, lock and environment identities, package Git trees,
39
+ archive paths, host compatibility, and a Lean probe before publication.
40
+ - Separate artifact compatibility identity from informational host metadata and
41
+ bump the environment store identity schema.
42
+ - Add verification, decision explanations, semantic context diffs, repeated profiles, and
43
+ bounded matrix execution over ordinary execution results.
44
+ - Add interruptible toolchain installation, Lake resolution, environment builds, matrix checks,
45
+ and project checks with process-group cleanup on cancellation and Ctrl-C.
46
+ - Ship the public JSON schemas in wheel and source distributions and expose `schema_path()`.
47
+ - Add reproducible case-study fixtures, clean-wheel smoke testing, and installed-wheel Lean
48
+ acceptance in CI.
49
+
50
+ ## 0.6.0
51
+
52
+ - Discover packages declared with either `lakefile.toml` or `lakefile.lean`.
53
+ - Translate Lake DSL configurations through the package's exact declared Lean
54
+ toolchain instead of parsing Lean source or guessing package metadata.
55
+
56
+ ## 0.5.0
57
+
58
+ - Add `Environment.execute()` for generic commands such as `lake exe`.
59
+ - Add managed `InteractiveSession` processes with live UTF-8 standard-I/O pipes.
60
+ - Run interactive tools in disposable environment clones with exact provenance.
61
+ - Enforce local timeout, memory, CPU, and bounded-transcript policies for sessions.
62
+ - Gracefully close sessions with stdin EOF before process-group termination.
63
+ - Persist final interactive `ExecutionResult` records and clean up instances.
64
+
65
+ ## 0.4.0
66
+
67
+ - Add `github:owner/repository@tag-or-commit` package references.
68
+ - Discover package identity, root module, and Lean toolchain from Lake projects.
69
+ - Pin convenience references to exact commits before environment resolution.
70
+ - Add one-shot `lean-runtime check FILE --with REFERENCE` execution.
71
+ - Add `Runtime.spec_from_references()`, `resolve_references()`,
72
+ `ensure_references()`, and `Runtime.check(..., packages=[...])`.
73
+ - Detect incompatible discovered toolchains across multi-package requests.
74
+ - Avoid Elan's implicit toolchain installation during installation checks.
75
+
76
+ ## 0.3.0
77
+
78
+ - Add safe multi-file checking and replayable multi-file captures.
79
+ - Add cancellable native asyncio helpers.
80
+ - Add structured lifecycle progress events.
81
+ - Resolve friendly Git tags into exact commit locks.
82
+ - Add installation health, cache status, environment listing, and richer inspection.
83
+ - Add a scheduled real-ecosystem compatibility profile.
84
+ - Store compact, content-verified one-commit source snapshots.
85
+ - Treat direct and transitive package toolchain files as compatibility signals,
86
+ while making the actual selected-toolchain build authoritative.
87
+ - Use execution leases so batch checks can clone concurrently without racing GC.
88
+ - Build imported locked-package roots on demand inside execution workspaces.
89
+ - Add release automation for PyPI trusted publishing.
90
+ - Build and deploy the documentation site through GitHub Pages.
91
+
92
+ ## 0.2.0
93
+
94
+ - Introduce content-addressed environments, exact Git locks, offline reopening,
95
+ execution provenance, captures, aliases, garbage collection, and trusted local
96
+ resource policies.
@@ -4,4 +4,5 @@ recursive-include docs *.md
4
4
  recursive-include examples *.toml
5
5
  recursive-include compatibility *.json *.md *.toml
6
6
  recursive-include scripts *.py
7
+ recursive-include schemas *.json
7
8
  recursive-include tests *.py
@@ -0,0 +1,175 @@
1
+ Metadata-Version: 2.4
2
+ Name: lean-runtime
3
+ Version: 1.0.0
4
+ Summary: Run Lean 4 proofs from Python or standalone files
5
+ Author: Alejandro Radisic
6
+ License-Expression: Apache-2.0
7
+ Project-URL: Homepage, https://github.com/alerad/lean-runtime
8
+ Project-URL: Documentation, https://alerad.github.io/lean-runtime/
9
+ Project-URL: Repository, https://github.com/alerad/lean-runtime.git
10
+ Project-URL: Issues, https://github.com/alerad/lean-runtime/issues
11
+ Project-URL: Changelog, https://github.com/alerad/lean-runtime/blob/main/CHANGELOG.md
12
+ Keywords: lean4,theorem-prover,formal-verification,toolchain
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Operating System :: MacOS
15
+ Classifier: Operating System :: POSIX :: Linux
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Typing :: Typed
21
+ Requires-Python: >=3.10
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ Requires-Dist: tomli>=2; python_version < "3.11"
25
+ Provides-Extra: dev
26
+ Requires-Dist: pytest>=8; extra == "dev"
27
+ Requires-Dist: ruff>=0.6; extra == "dev"
28
+ Requires-Dist: mypy>=1.10; extra == "dev"
29
+ Requires-Dist: tomli>=2; extra == "dev"
30
+ Requires-Dist: jsonschema>=4.23; extra == "dev"
31
+ Provides-Extra: docs
32
+ Requires-Dist: mkdocs<2,>=1.6; extra == "docs"
33
+ Requires-Dist: mkdocs-material>=9.5; extra == "docs"
34
+ Dynamic: license-file
35
+
36
+ # Lean Runtime
37
+
38
+ Run Lean proofs from Python or a single `.lean` file—without creating a throwaway
39
+ Lake project or rebuilding the same dependencies on every machine.
40
+
41
+ Lean Runtime discovers or resolves the environment, checks a global OCI cache,
42
+ and returns structured Lean results with exact provenance.
43
+
44
+ > **Status:** V1 beta. The local backend runs trusted Lean, Lake, and package code;
45
+ > it is an orchestration boundary, not a security sandbox.
46
+
47
+ ## Install
48
+
49
+ ```bash
50
+ python -m pip install lean-runtime
51
+ ```
52
+
53
+ Lean Runtime manages its own Elan installation on macOS and Linux. Windows
54
+ currently requires `LEAN_RUNTIME_ELAN`.
55
+
56
+ ## Run one Lean file
57
+
58
+ Inside an existing pinned Lake project, just pass the file:
59
+
60
+ ```bash
61
+ lean-run MyProject/Main.lean
62
+ ```
63
+
64
+ For a portable standalone file, declare exact dependencies in TOML frontmatter:
65
+
66
+ ```lean
67
+ -- /// lean-runtime
68
+ -- requires = ["mathlib@v4.32.2"]
69
+ -- ///
70
+
71
+ import Mathlib
72
+
73
+ example : 2 + 2 = 4 := by norm_num
74
+ ```
75
+
76
+ ```bash
77
+ lean-run Main.lean
78
+ ```
79
+
80
+ The same context can be supplied from the command line:
81
+
82
+ ```bash
83
+ lean-run Main.lean --with mathlib@v4.32.2
84
+ ```
85
+
86
+ Create an exact lock for CI without changing the file:
87
+
88
+ ```bash
89
+ lean-run Main.lean --with mathlib@v4.32.2 \
90
+ --lock-out environment.lock.json
91
+ lean-run Main.lean --lock environment.lock.json
92
+ ```
93
+
94
+ ## Python
95
+
96
+ Configure an environment once, then use it repeatedly:
97
+
98
+ ```python
99
+ import lean_runtime as lean
100
+
101
+ env = lean.setup(["mathlib@v4.32.2"])
102
+
103
+ result = env.check(
104
+ """
105
+ import Mathlib
106
+ example : 2 + 2 = 4 := by norm_num
107
+ """
108
+ )
109
+ result.raise_for_error()
110
+ ```
111
+
112
+ Batch and asyncio APIs reuse that prepared environment:
113
+
114
+ ```python
115
+ results = env.check_many(generated_proofs, concurrency=8)
116
+ results = await env.check_many_async(generated_proofs, concurrency=20)
117
+ ```
118
+
119
+ Local projects use the same setup pattern while retaining mutable-project
120
+ semantics:
121
+
122
+ ```python
123
+ project = lean.setup(project="./my-project")
124
+ result = project.check_file("./my-project/MyProject/Main.lean")
125
+ ```
126
+
127
+ One-shot helpers are available when setup reuse is unnecessary:
128
+
129
+ ```python
130
+ result = lean.check(source, deps=["mathlib@v4.32.2"])
131
+ result = lean.check_file("./my-project/MyProject/Main.lean")
132
+ ```
133
+
134
+ When you need evidence rather than extra setup, the operations CLI can verify, explain,
135
+ compare, and measure the same exact contexts:
136
+
137
+ ```bash
138
+ lean-runtime verify research-stack --offline
139
+ lean-runtime diff previous.lock.json environment.lock.json
140
+ lean-runtime profile research-stack Main.lean --repeat 5
141
+ lean-runtime matrix compatibility.toml Main.lean
142
+ ```
143
+
144
+ Use `lean-run Main.lean --explain` to inspect context routing without executing Lean, and
145
+ `--timings` to expose preparation versus execution time. Successful ordinary checks remain
146
+ one concise line.
147
+
148
+ Friendly references remain exact: use `mathlib@VERSION`,
149
+ `leancert@VERSION`, `owner/repository@REVISION`, or the explicit
150
+ `github:owner/repository@REVISION` form. Bare floating package names are never
151
+ accepted.
152
+
153
+ ## Under the hood
154
+
155
+ The simple API is backed by exact Git commits and trees, Lake-resolved locks,
156
+ platform-aware content-addressed environments, atomic cross-process builds,
157
+ transparent OCI cache reuse, replayable provenance, verification, and signed
158
+ attestations. Advanced users can access all of it through `lean_runtime.Runtime`
159
+ and the `lean-runtime` operations CLI.
160
+
161
+ ## Documentation
162
+
163
+ - [Getting started](https://github.com/alerad/lean-runtime/blob/main/docs/getting-started.md)
164
+ - [Python API](https://github.com/alerad/lean-runtime/blob/main/docs/python-api.md)
165
+ - [`lean-run` and operations CLI](https://github.com/alerad/lean-runtime/blob/main/docs/cli.md)
166
+ - [Managed environments](https://github.com/alerad/lean-runtime/blob/main/docs/environments.md)
167
+ - [Local Lake projects](https://github.com/alerad/lean-runtime/blob/main/docs/local-projects.md)
168
+ - [Environment bundles and OCI caches](https://github.com/alerad/lean-runtime/blob/main/docs/bundles.md)
169
+ - [Architecture](https://github.com/alerad/lean-runtime/blob/main/docs/architecture.md)
170
+ - [Trust and limitations](https://github.com/alerad/lean-runtime/blob/main/docs/trust-and-limitations.md)
171
+ - [V1 release case study](https://github.com/alerad/lean-runtime/blob/main/docs/case-study-v1.md)
172
+
173
+ ## License
174
+
175
+ Apache License 2.0.
@@ -0,0 +1,140 @@
1
+ # Lean Runtime
2
+
3
+ Run Lean proofs from Python or a single `.lean` file—without creating a throwaway
4
+ Lake project or rebuilding the same dependencies on every machine.
5
+
6
+ Lean Runtime discovers or resolves the environment, checks a global OCI cache,
7
+ and returns structured Lean results with exact provenance.
8
+
9
+ > **Status:** V1 beta. The local backend runs trusted Lean, Lake, and package code;
10
+ > it is an orchestration boundary, not a security sandbox.
11
+
12
+ ## Install
13
+
14
+ ```bash
15
+ python -m pip install lean-runtime
16
+ ```
17
+
18
+ Lean Runtime manages its own Elan installation on macOS and Linux. Windows
19
+ currently requires `LEAN_RUNTIME_ELAN`.
20
+
21
+ ## Run one Lean file
22
+
23
+ Inside an existing pinned Lake project, just pass the file:
24
+
25
+ ```bash
26
+ lean-run MyProject/Main.lean
27
+ ```
28
+
29
+ For a portable standalone file, declare exact dependencies in TOML frontmatter:
30
+
31
+ ```lean
32
+ -- /// lean-runtime
33
+ -- requires = ["mathlib@v4.32.2"]
34
+ -- ///
35
+
36
+ import Mathlib
37
+
38
+ example : 2 + 2 = 4 := by norm_num
39
+ ```
40
+
41
+ ```bash
42
+ lean-run Main.lean
43
+ ```
44
+
45
+ The same context can be supplied from the command line:
46
+
47
+ ```bash
48
+ lean-run Main.lean --with mathlib@v4.32.2
49
+ ```
50
+
51
+ Create an exact lock for CI without changing the file:
52
+
53
+ ```bash
54
+ lean-run Main.lean --with mathlib@v4.32.2 \
55
+ --lock-out environment.lock.json
56
+ lean-run Main.lean --lock environment.lock.json
57
+ ```
58
+
59
+ ## Python
60
+
61
+ Configure an environment once, then use it repeatedly:
62
+
63
+ ```python
64
+ import lean_runtime as lean
65
+
66
+ env = lean.setup(["mathlib@v4.32.2"])
67
+
68
+ result = env.check(
69
+ """
70
+ import Mathlib
71
+ example : 2 + 2 = 4 := by norm_num
72
+ """
73
+ )
74
+ result.raise_for_error()
75
+ ```
76
+
77
+ Batch and asyncio APIs reuse that prepared environment:
78
+
79
+ ```python
80
+ results = env.check_many(generated_proofs, concurrency=8)
81
+ results = await env.check_many_async(generated_proofs, concurrency=20)
82
+ ```
83
+
84
+ Local projects use the same setup pattern while retaining mutable-project
85
+ semantics:
86
+
87
+ ```python
88
+ project = lean.setup(project="./my-project")
89
+ result = project.check_file("./my-project/MyProject/Main.lean")
90
+ ```
91
+
92
+ One-shot helpers are available when setup reuse is unnecessary:
93
+
94
+ ```python
95
+ result = lean.check(source, deps=["mathlib@v4.32.2"])
96
+ result = lean.check_file("./my-project/MyProject/Main.lean")
97
+ ```
98
+
99
+ When you need evidence rather than extra setup, the operations CLI can verify, explain,
100
+ compare, and measure the same exact contexts:
101
+
102
+ ```bash
103
+ lean-runtime verify research-stack --offline
104
+ lean-runtime diff previous.lock.json environment.lock.json
105
+ lean-runtime profile research-stack Main.lean --repeat 5
106
+ lean-runtime matrix compatibility.toml Main.lean
107
+ ```
108
+
109
+ Use `lean-run Main.lean --explain` to inspect context routing without executing Lean, and
110
+ `--timings` to expose preparation versus execution time. Successful ordinary checks remain
111
+ one concise line.
112
+
113
+ Friendly references remain exact: use `mathlib@VERSION`,
114
+ `leancert@VERSION`, `owner/repository@REVISION`, or the explicit
115
+ `github:owner/repository@REVISION` form. Bare floating package names are never
116
+ accepted.
117
+
118
+ ## Under the hood
119
+
120
+ The simple API is backed by exact Git commits and trees, Lake-resolved locks,
121
+ platform-aware content-addressed environments, atomic cross-process builds,
122
+ transparent OCI cache reuse, replayable provenance, verification, and signed
123
+ attestations. Advanced users can access all of it through `lean_runtime.Runtime`
124
+ and the `lean-runtime` operations CLI.
125
+
126
+ ## Documentation
127
+
128
+ - [Getting started](https://github.com/alerad/lean-runtime/blob/main/docs/getting-started.md)
129
+ - [Python API](https://github.com/alerad/lean-runtime/blob/main/docs/python-api.md)
130
+ - [`lean-run` and operations CLI](https://github.com/alerad/lean-runtime/blob/main/docs/cli.md)
131
+ - [Managed environments](https://github.com/alerad/lean-runtime/blob/main/docs/environments.md)
132
+ - [Local Lake projects](https://github.com/alerad/lean-runtime/blob/main/docs/local-projects.md)
133
+ - [Environment bundles and OCI caches](https://github.com/alerad/lean-runtime/blob/main/docs/bundles.md)
134
+ - [Architecture](https://github.com/alerad/lean-runtime/blob/main/docs/architecture.md)
135
+ - [Trust and limitations](https://github.com/alerad/lean-runtime/blob/main/docs/trust-and-limitations.md)
136
+ - [V1 release case study](https://github.com/alerad/lean-runtime/blob/main/docs/case-study-v1.md)
137
+
138
+ ## License
139
+
140
+ Apache License 2.0.
@@ -0,0 +1,222 @@
1
+ # Environment bundles
2
+
3
+ Lean Runtime can move an already built environment between compatible machines
4
+ without rebuilding its Lake packages:
5
+
6
+ ```bash
7
+ lean-runtime export research-stack --output research-stack.oci.tar.gz
8
+ lean-runtime --home /tmp/fresh import research-stack.oci.tar.gz --name research-stack
9
+ ```
10
+
11
+ The equivalent Python API is:
12
+
13
+ ```python
14
+ info = runtime.export_environment("research-stack", "research-stack.oci.tar.gz")
15
+ environment = another_runtime.import_environment("research-stack.oci.tar.gz", name="research-stack")
16
+ ```
17
+
18
+ Import verifies the OCI manifest and every blob digest, recomputes the lock and
19
+ environment identities, requires an exact platform compatibility match, checks
20
+ each package's Git commit and tree, and runs a Lean probe. Publication uses a
21
+ staging directory and atomic rename, so a failed import is never visible as a
22
+ ready environment. `--no-probe` exists for inspection and testing workflows;
23
+ normal imports should keep the probe enabled.
24
+
25
+ Layer construction, archive writing, import, and registry downloads are
26
+ disk-backed and streamed. Peak memory does not scale with package-layer size.
27
+
28
+ ## OCI global caches
29
+
30
+ By default, Lean Runtime checks the public
31
+ `oci://ghcr.io/alerad/lean-runtime-cache` mirror. A miss or availability failure
32
+ falls back to the existing source build, so environment specifications do not
33
+ change. Set `LEAN_RUNTIME_CACHES=` or construct `Runtime(caches=[])` to disable
34
+ all remote cache lookups.
35
+
36
+ Configure one or more cache repositories without changing the environment
37
+ specification or lock:
38
+
39
+ ```python
40
+ runtime = Runtime(
41
+ caches=["oci://ghcr.io/alerad/leancert-runtime"],
42
+ prebuilt="auto",
43
+ )
44
+ environment = runtime.ensure(lock)
45
+ ```
46
+
47
+ The equivalent environment variables are:
48
+
49
+ ```bash
50
+ export LEAN_RUNTIME_CACHES=oci://ghcr.io/alerad/leancert-runtime
51
+ export LEAN_RUNTIME_PREBUILT=auto
52
+ ```
53
+
54
+ `auto` tries caches in order and builds from source when an artifact is absent,
55
+ incompatible, or temporarily unavailable. `require` makes an ordinary cache
56
+ miss an error. `never` disables remote lookup. Digest, lock, archive-safety, and
57
+ probe failures are security failures and never silently fall back to source.
58
+
59
+ Explicit prefetch uses the same verified path:
60
+
61
+ ```bash
62
+ lean-runtime \
63
+ --cache oci://ghcr.io/alerad/leancert-runtime \
64
+ pull environment.lock.json
65
+ ```
66
+
67
+ Registry blobs are retained content-addressed under the runtime home. Pulling a
68
+ second environment with an identical package layer reuses it without another
69
+ download.
70
+
71
+ Old blobs can be included in garbage collection explicitly:
72
+
73
+ ```bash
74
+ # Preview, then apply after reviewing the candidates.
75
+ lean-runtime gc --include-blobs
76
+ lean-runtime gc --include-blobs --execute
77
+ ```
78
+
79
+ Blobs referenced by an imported environment or leased by an active pull are
80
+ retained. Collection rechecks both conditions while holding the same per-blob
81
+ lock used by downloads.
82
+
83
+ ### Required publisher signatures
84
+
85
+ For high-trust workflows, require a Sigstore signature from one exact GitHub
86
+ Actions identity:
87
+
88
+ ```python
89
+ runtime = Runtime(
90
+ caches=["oci://ghcr.io/alerad/leancert-runtime"],
91
+ signatures="require",
92
+ trusted_identity=(
93
+ "https://github.com/alerad/leancert/.github/workflows/cache.yml@refs/heads/main"
94
+ ),
95
+ trusted_issuer="https://token.actions.githubusercontent.com",
96
+ )
97
+ ```
98
+
99
+ CLI equivalents are `--signatures require`, `--trusted-identity`, and
100
+ `--trusted-issuer`. Verification uses an installed Cosign 2.6.2 or 3.0.4+ and
101
+ binds the canonical lock-index digest, certificate identity, issuer, and
102
+ transparency-log claims. Older versions are rejected because of the patched
103
+ [Cosign verification advisory](https://github.com/sigstore/cosign/security/advisories/GHSA-whqx-f9j3-ch6m).
104
+
105
+ Signature failure is an integrity failure and never triggers source fallback.
106
+
107
+ ## Publishing
108
+
109
+ Publish the current platform after ensuring the lock:
110
+
111
+ ```bash
112
+ export LEAN_RUNTIME_REGISTRY_USERNAME=alerad
113
+ export LEAN_RUNTIME_REGISTRY_PASSWORD="$GHCR_TOKEN"
114
+
115
+ lean-runtime build-and-push environment.lock.json \
116
+ --push-to oci://ghcr.io/alerad/leancert-runtime \
117
+ --tag v4.32.2.4 \
118
+ --sign --attest
119
+ ```
120
+
121
+ The publisher checks for existing blobs, uploads only missing content, publishes
122
+ the platform manifest by digest, and updates the canonical `lock_<sha>` index
123
+ tag last. Human tags are aliases to that same index. This follows the
124
+ [OCI Distribution Specification](https://github.com/opencontainers/distribution-spec/blob/main/spec.md)
125
+ and uses an [OCI image index](https://github.com/opencontainers/image-spec/blob/main/image-index.md)
126
+ for platform selection.
127
+
128
+ Repository authors can use the bundled composite action after checking out the
129
+ repository and generating or retaining a lock:
130
+
131
+ ```yaml
132
+ permissions:
133
+ contents: read
134
+ packages: write
135
+
136
+ steps:
137
+ - uses: actions/checkout@v4
138
+ - uses: ./.github/actions/cache
139
+ with:
140
+ lock: environment.lock.json
141
+ repository: oci://ghcr.io/${{ github.repository_owner }}/leancert-runtime
142
+ tag: ${{ github.ref_name }}
143
+ registry-username: ${{ github.actor }}
144
+ registry-password: ${{ secrets.GITHUB_TOKEN }}
145
+ ```
146
+
147
+ For a build matrix, have each platform publish without changing the canonical
148
+ index and retain its JSON result:
149
+
150
+ ```bash
151
+ lean-runtime build-and-push environment.lock.json \
152
+ --push-to oci://ghcr.io/alerad/leancert-runtime \
153
+ --platform-only > platform-result.json
154
+ ```
155
+
156
+ After collecting the result files, one final job publishes the deterministic
157
+ multi-platform index and human aliases:
158
+
159
+ ```bash
160
+ lean-runtime publish-index "$LOCK_ID" results/*.json \
161
+ --repository oci://ghcr.io/alerad/leancert-runtime \
162
+ --tag "$GITHUB_REF_NAME"
163
+ ```
164
+
165
+ The finalizer rejects duplicate OS/architecture/ABI entries. Publishing the
166
+ index only after every required platform succeeds prevents partial build
167
+ matrices from replacing a complete cache release.
168
+
169
+ `--attest` runs package-source verification and the Lean import probe, records a
170
+ stable inventory of all Lake build outputs, and publishes that predicate as a
171
+ keyless Cosign attestation bound to the platform manifest (or finalized index).
172
+ It requires Cosign and an OIDC-capable publishing environment.
173
+
174
+ ## Auditing
175
+
176
+ Verify the embedded source markers, Git commits and trees, root lock material,
177
+ Lean probe, and build-output inventory at any time:
178
+
179
+ ```bash
180
+ lean-runtime verify research-stack
181
+ ```
182
+
183
+ For an independent check, reacquire and rebuild the exact lock in a temporary
184
+ store and compare normalized artifact inventories:
185
+
186
+ ```bash
187
+ lean-runtime verify research-stack --rebuild
188
+ ```
189
+
190
+ `source_verified` and `probe_passed` are the trust result. `artifact_match` is a
191
+ separate byte-reproducibility measurement: a mismatch is reported but is not
192
+ treated as failed source/proof verification, because native toolchains and package build
193
+ steps are not promised to produce byte-identical artifacts.
194
+
195
+ ## Format version 1
196
+
197
+ The gzip file is a deterministic OCI image-layout archive. It contains a
198
+ standard `oci-layout`, `index.json`, one image manifest, a Lean Runtime config
199
+ blob, and content-addressed layer blobs. The config contains the complete
200
+ `EnvironmentLock`, build profile, environment identity, and platform
201
+ compatibility record.
202
+
203
+ There is one layer for the synthetic root workspace and one layer for each Lake
204
+ package. Package layers include both source and `.lake/build`, so identical
205
+ serialized package trees are reused by the registry transport. The Lean
206
+ toolchain is not bundled; Elan supplies the exact toolchain named by the lock.
207
+
208
+ Archives use sorted paths, zero timestamps and ownership, normalized tar
209
+ metadata, canonical JSON, and deterministic gzip headers. Exporting an unchanged
210
+ environment twice therefore produces identical bytes and digests.
211
+
212
+ ## Compatibility and trust
213
+
214
+ `lock_id` identifies the platform-independent locked source graph.
215
+ `environment_id` additionally includes the release build profile and the
216
+ versioned platform compatibility record. Informational host details remain in
217
+ metadata but do not invalidate compatible caches across OS patch releases.
218
+
219
+ A bundle is trusted executable build output. Digest, lock, Git-tree, and probe
220
+ verification detect corruption and identity substitution, but do not prove that
221
+ the builder compiled the sources faithfully. Registry credentials authenticate
222
+ access but are not a builder attestation; only use cache publishers you trust.
@@ -0,0 +1,47 @@
1
+ # V1 release case study
2
+
3
+ The release case study demonstrates the public lifecycle rather than relying on private
4
+ benchmark hooks. It uses a prepared exact Mathlib environment and the committed mixture of
5
+ accepted proofs, elaboration failures, and malformed input.
6
+
7
+ ## Run the evidence harness
8
+
9
+ ```bash
10
+ python scripts/run_v1_case_study.py research-stack \
11
+ --concurrency 1 --concurrency 4 --concurrency 8 --concurrency 20 \
12
+ --repeat 5 --output benchmarks/proof_batch/results.json
13
+ ```
14
+
15
+ The resulting JSON records:
16
+
17
+ - runtime, Python, platform, command, and fixture identity;
18
+ - cache state before and after the workload;
19
+ - raw wall-time samples and min/median/mean/p95/max by concurrency;
20
+ - stable request identity and unique execution identity;
21
+ - bundle size and export/import durations;
22
+ - import into an empty runtime home;
23
+ - offline verification and captured-execution replay.
24
+
25
+ The harness deliberately starts from an already prepared environment. Measure cold source
26
+ preparation separately and state whether local, Lake, and OCI caches were empty. Do not combine
27
+ cold source builds and warm execution into one headline number.
28
+
29
+ ## Clean-wheel acceptance
30
+
31
+ Build and exercise the artifact users actually install:
32
+
33
+ ```bash
34
+ python -m build
35
+ python scripts/smoke_wheel.py dist/lean_runtime-1.0.0-py3-none-any.whl
36
+ ```
37
+
38
+ Add `--lean` to bootstrap an isolated runtime home and run a real standalone proof. The smoke
39
+ script creates a fresh virtual environment, installs only the wheel, clears ambient Python
40
+ package visibility, checks both console entry points, and reads a packaged v1 schema through
41
+ `lean_runtime.schema_path()`.
42
+
43
+ ## Publishing results
44
+
45
+ Keep the raw JSON beside any summary. Record the exact lock and environment ID, machine and
46
+ filesystem, command line, runtime version, repetition count, and cache state. Timings from noisy
47
+ shared CI are evidence that the workflow completes, not a performance regression gate.