lean-runtime 2.6.2__tar.gz → 2.7.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 (182) hide show
  1. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/CHANGELOG.md +17 -0
  2. {lean_runtime-2.6.2/lean_runtime.egg-info → lean_runtime-2.7.0}/PKG-INFO +3 -1
  3. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/README.md +2 -0
  4. lean_runtime-2.7.0/compatibility/README.md +14 -0
  5. lean_runtime-2.7.0/compatibility/lake-artifact-cache-4.33.0.json +32 -0
  6. lean_runtime-2.7.0/compatibility/mathlib-4.32.2.json +8 -0
  7. lean_runtime-2.7.0/compatibility/mathlib-4.33.0.json +8 -0
  8. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/docs/architecture.md +16 -0
  9. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/docs/getting-started.md +4 -1
  10. lean_runtime-2.7.0/docs/lake-artifact-cache-design.md +154 -0
  11. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/docs/local-projects.md +18 -1
  12. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/bundles.py +16 -65
  13. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/cli.py +44 -11
  14. lean_runtime-2.7.0/lean_runtime/lake_cache.py +212 -0
  15. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/oci.py +14 -37
  16. lean_runtime-2.7.0/lean_runtime/oci_protocol.py +116 -0
  17. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/programs.py +18 -20
  18. lean_runtime-2.7.0/lean_runtime/project_execution.py +192 -0
  19. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/projects.py +9 -0
  20. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/runtime.py +57 -78
  21. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/toolchain_oci.py +21 -22
  22. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/toolchains.py +48 -0
  23. {lean_runtime-2.6.2 → lean_runtime-2.7.0/lean_runtime.egg-info}/PKG-INFO +3 -1
  24. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime.egg-info/SOURCES.txt +8 -0
  25. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/mkdocs.yml +1 -0
  26. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/pyproject.toml +1 -1
  27. lean_runtime-2.7.0/scripts/lake_cache_gate.py +77 -0
  28. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/scripts/run_compatibility.py +13 -4
  29. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/discovery/test_planner.py +13 -0
  30. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_cli.py +78 -0
  31. lean_runtime-2.7.0/tests/test_lake_cache.py +86 -0
  32. lean_runtime-2.7.0/tests/test_oci_protocol.py +59 -0
  33. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_projects.py +26 -0
  34. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_toolchains.py +45 -0
  35. lean_runtime-2.6.2/compatibility/README.md +0 -13
  36. lean_runtime-2.6.2/compatibility/mathlib-4.32.2.json +0 -15
  37. lean_runtime-2.6.2/compatibility/mathlib-4.33.0.json +0 -15
  38. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/LICENSE +0 -0
  39. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/MANIFEST.in +0 -0
  40. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/catalog/environments.toml +0 -0
  41. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/catalog/locks/core-v4.32.2.lock.json +0 -0
  42. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/catalog/locks/leancert-v4.30.0.5.lock.json +0 -0
  43. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/catalog/locks/leancert-v4.31.0.lock.json +0 -0
  44. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/catalog/locks/leancert-v4.32.2.4.lock.json +0 -0
  45. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/catalog/locks/leancert-v4.33.0.lock.json +0 -0
  46. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/catalog/locks/mathlib-v4.30.0.lock.json +0 -0
  47. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/catalog/locks/mathlib-v4.31.0.lock.json +0 -0
  48. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/catalog/locks/mathlib-v4.32.2.lock.json +0 -0
  49. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/catalog/locks/mathlib-v4.33.0.lock.json +0 -0
  50. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/compatibility/mathlib-4.32.2.toml +0 -0
  51. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/compatibility/mathlib-4.33.0.toml +0 -0
  52. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/docs/captures.md +0 -0
  53. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/docs/case-study-v1.md +0 -0
  54. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/docs/cli.md +0 -0
  55. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/docs/development.md +0 -0
  56. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/docs/environments.md +0 -0
  57. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/docs/index.md +0 -0
  58. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/docs/portable-copies.md +0 -0
  59. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/docs/project-publishing.md +0 -0
  60. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/docs/python-api.md +0 -0
  61. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/docs/ready-programs.md +0 -0
  62. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/docs/standalone-files.md +0 -0
  63. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/docs/trust-and-limitations.md +0 -0
  64. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/docs/v1-precision.md +0 -0
  65. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/examples/mathlib.toml +0 -0
  66. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/__init__.py +0 -0
  67. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/__main__.py +0 -0
  68. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/_git.py +0 -0
  69. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/_paths.py +0 -0
  70. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/backends.py +0 -0
  71. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/capsules.py +0 -0
  72. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/comparison.py +0 -0
  73. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/console.py +0 -0
  74. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/decisions.py +0 -0
  75. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/diagnostics.py +0 -0
  76. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/discovery/__init__.py +0 -0
  77. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/discovery/analyzer.py +0 -0
  78. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/discovery/api.py +0 -0
  79. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/discovery/candidate.py +0 -0
  80. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/discovery/catalog.py +0 -0
  81. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/discovery/catalog_build.py +0 -0
  82. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/discovery/catalog_cli.py +0 -0
  83. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/discovery/catalog_manifest.py +0 -0
  84. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/discovery/data/catalog.json +0 -0
  85. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/discovery/defaults.py +0 -0
  86. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/discovery/engine.py +0 -0
  87. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/discovery/errors.py +0 -0
  88. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/discovery/module_inventory.py +0 -0
  89. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/discovery/planner.py +0 -0
  90. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/discovery/policy.py +0 -0
  91. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/discovery/probe.py +0 -0
  92. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/discovery/py.typed +0 -0
  93. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/discovery/result.py +0 -0
  94. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/discovery/schema_resources.py +0 -0
  95. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/discovery/schemas/catalog-v1.schema.json +0 -0
  96. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/discovery/schemas/plan-v1.schema.json +0 -0
  97. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/discovery/schemas/result-v1.schema.json +0 -0
  98. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/environments.py +0 -0
  99. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/errors.py +0 -0
  100. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/events.py +0 -0
  101. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/facade.py +0 -0
  102. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/frontmatter.py +0 -0
  103. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/health.py +0 -0
  104. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/lake.py +0 -0
  105. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/lockfiles.py +0 -0
  106. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/locking.py +0 -0
  107. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/matrix.py +0 -0
  108. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/models.py +0 -0
  109. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/packs.py +0 -0
  110. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/policies.py +0 -0
  111. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/profiling.py +0 -0
  112. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/project_sharing.py +0 -0
  113. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/publisher_verification.py +0 -0
  114. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/py.typed +0 -0
  115. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/references.py +0 -0
  116. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/resolver.py +0 -0
  117. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/run_cli.py +0 -0
  118. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/schema_resources.py +0 -0
  119. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/serialization.py +0 -0
  120. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/shared_projects.py +0 -0
  121. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/specs.py +0 -0
  122. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/store.py +0 -0
  123. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/timings.py +0 -0
  124. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/toolchain_slim.py +0 -0
  125. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/verification.py +0 -0
  126. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/wire.py +0 -0
  127. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime.egg-info/dependency_links.txt +0 -0
  128. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime.egg-info/entry_points.txt +0 -0
  129. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime.egg-info/requires.txt +0 -0
  130. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime.egg-info/top_level.txt +0 -0
  131. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/schemas/cleanup-v1.schema.json +0 -0
  132. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/schemas/comparison-v1.schema.json +0 -0
  133. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/schemas/execution-v1.schema.json +0 -0
  134. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/schemas/inspect-v1.schema.json +0 -0
  135. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/schemas/matrix-v1.schema.json +0 -0
  136. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/schemas/profile-v1.schema.json +0 -0
  137. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/schemas/verify-v1.schema.json +0 -0
  138. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/scripts/announcement_gate.py +0 -0
  139. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/scripts/registry_preflight.py +0 -0
  140. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/scripts/run_v1_case_study.py +0 -0
  141. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/scripts/smoke_wheel.py +0 -0
  142. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/setup.cfg +0 -0
  143. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/conftest.py +0 -0
  144. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/discovery/e2e/test_real_discovery.py +0 -0
  145. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/discovery/test_analyzer.py +0 -0
  146. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/discovery/test_catalog.py +0 -0
  147. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/discovery/test_catalog_build.py +0 -0
  148. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/discovery/test_discovery_schema_resources.py +0 -0
  149. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/discovery/test_engine.py +0 -0
  150. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/discovery/test_policy.py +0 -0
  151. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_backend.py +0 -0
  152. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_bundles.py +0 -0
  153. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_capsules.py +0 -0
  154. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_console.py +0 -0
  155. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_diagnostics.py +0 -0
  156. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_environment_integration.py +0 -0
  157. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_events_health.py +0 -0
  158. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_facade.py +0 -0
  159. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_frontmatter.py +0 -0
  160. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_git.py +0 -0
  161. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_interactive.py +0 -0
  162. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_lockfiles.py +0 -0
  163. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_models.py +0 -0
  164. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_multifile.py +0 -0
  165. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_packs.py +0 -0
  166. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_paths.py +0 -0
  167. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_prebuilt_policy.py +0 -0
  168. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_programs.py +0 -0
  169. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_project_publish.py +0 -0
  170. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_references.py +0 -0
  171. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_run_cli.py +0 -0
  172. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_runtime.py +0 -0
  173. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_schema_resources.py +0 -0
  174. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_schemas.py +0 -0
  175. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_signatures.py +0 -0
  176. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_specs.py +0 -0
  177. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_store.py +0 -0
  178. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_toolchain_oci.py +0 -0
  179. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_toolchain_slim.py +0 -0
  180. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_v1_precision.py +0 -0
  181. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_verification_inventory.py +0 -0
  182. {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_verification_probe.py +0 -0
@@ -2,6 +2,23 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 2.7.0 - 2026-08-14
6
+
7
+ - Keep newly initialized project roots narrow: the generated root imports its
8
+ local `Basic` module without redundantly importing the all-Mathlib umbrella,
9
+ and the completion hint points to the fast first-file check.
10
+ - Render stdin diagnostics as `<stdin>` in the CLI instead of exposing the
11
+ disposable `.lake/lean-runtime` staging path.
12
+ - Add fileless `lean-runtime check` and `ProjectEnvironment.check_all()` to
13
+ check every declared local library through Lake's `leanArts` facets, retaining
14
+ correct intra-project dependency ordering without building executables.
15
+ - Integrate an ABI- and toolchain-isolated root-project Lake artifact cache for
16
+ projects created by `init`. Capability support is probed and persisted rather
17
+ than version-gated; dependencies remain in the verified shared workspace.
18
+ - Keep remote Lake mappings fail-closed until artifacts have a verified SHA-256
19
+ inventory and lazy restoration participates in acquisition planning and
20
+ download limits.
21
+
5
22
  ## 2.6.2 - 2026-08-14
6
23
 
7
24
  - Keep an existing initialization target's directory inode alive, so running
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lean-runtime
3
- Version: 2.6.2
3
+ Version: 2.7.0
4
4
  Summary: Run Lean 4 proofs from Python or standalone files
5
5
  Author: Alejandro Radisic
6
6
  License-Expression: Apache-2.0
@@ -188,6 +188,8 @@ default, and exact dependencies are shared automatically:
188
188
  lean-runtime init MyProof
189
189
  cd MyProof
190
190
  lean-runtime check MyProof/Basic.lean
191
+ # Check every declared local library, in Lake dependency order:
192
+ lean-runtime check
191
193
  lean-runtime build
192
194
  ```
193
195
 
@@ -152,6 +152,8 @@ default, and exact dependencies are shared automatically:
152
152
  lean-runtime init MyProof
153
153
  cd MyProof
154
154
  lean-runtime check MyProof/Basic.lean
155
+ # Check every declared local library, in Lake dependency order:
156
+ lean-runtime check
155
157
  lean-runtime build
156
158
  ```
157
159
 
@@ -0,0 +1,14 @@
1
+ # Compatibility profiles
2
+
3
+ Profiles exercise published environments rather than mocking Lake. The Mathlib
4
+ 4.32.2 and 4.33.0 profiles independently acquire their bundled exact catalog
5
+ locks and import the public `Mathlib` root. Transitive packages remain attested
6
+ in the lock but are not advertised as independent catalog roots.
7
+
8
+ ```bash
9
+ python scripts/run_compatibility.py compatibility/mathlib-4.32.2.json
10
+ python scripts/run_compatibility.py compatibility/mathlib-4.33.0.json
11
+ ```
12
+
13
+ The first run downloads the verified sparse environment. Later runs reuse its
14
+ content-addressed artifacts and published workspace.
@@ -0,0 +1,32 @@
1
+ {
2
+ "schema": "lean-runtime.lake-cache-contract/v1",
3
+ "toolchain": "leanprover/lean4:v4.33.0",
4
+ "lake_version_observed": "5.0.0-src+d8b1897",
5
+ "capability_probes": {
6
+ "build_mappings": ["lake", "build", "--help"],
7
+ "cache_add": ["lake", "cache", "add", "--help"]
8
+ },
9
+ "configuration": {
10
+ "cache_root": "LAKE_CACHE_DIR",
11
+ "workspace_cache": "LAKE_ARTIFACT_CACHE",
12
+ "restore": "LAKE_RESTORE_ARTIFACTS",
13
+ "root_package_opt_in": "enableArtifactCache = true"
14
+ },
15
+ "observable_hit_signals": [
16
+ "found artifact in cache",
17
+ "restored artifact from cache",
18
+ "downloaded artifact"
19
+ ],
20
+ "experiment": {
21
+ "broad_cache_bytes": 6500000000,
22
+ "explicit_library_jobs": 8708,
23
+ "root_only_cache_bytes": 396000,
24
+ "root_restore_seconds": 5.17,
25
+ "dependency_heavy_fixture": "mathlib consumer",
26
+ "focused_lake_env_lean_uses_artifact_cache": false
27
+ },
28
+ "security": {
29
+ "lake_remote_hash_cryptographic": false,
30
+ "remote_registration": "disabled_pending_attested_sha256_inventory"
31
+ }
32
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "name": "mathlib-4.32.2",
3
+ "reference": "mathlib@v4.32.2",
4
+ "spec": "mathlib-4.32.2.toml",
5
+ "imports": [
6
+ "Mathlib"
7
+ ]
8
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "name": "mathlib-4.33.0",
3
+ "reference": "mathlib@v4.33.0",
4
+ "spec": "mathlib-4.33.0.toml",
5
+ "imports": [
6
+ "Mathlib"
7
+ ]
8
+ }
@@ -39,6 +39,22 @@ published environment identity includes platform and build-profile inputs.
39
39
  Each execution attempt has a unique history identity. A separate stable request
40
40
  digest includes the environment, input digest, operation, and requested policy.
41
41
 
42
+ ## Internal ownership
43
+
44
+ The high-level `Runtime` is a compatibility facade rather than the owner of
45
+ every workflow. Environment resolution and materialization remain in their
46
+ dedicated managers. Mutable local-project checks and builds pass through
47
+ `ProjectExecutor`, which owns Lake command selection and shared-workspace build
48
+ locking. This is the integration boundary for Lake facilities such as its
49
+ artifact cache; `Runtime` should not grow a second project build planner.
50
+
51
+ Environment capsules, slim toolchains, and ready-to-run programs have distinct
52
+ payload schemas. Their common OCI descriptor, digest, JSON, and platform
53
+ selection contract lives in `oci_protocol`. Payload implementations must not
54
+ import another payload implementation's private protocol helpers. Existing
55
+ legacy bundle readers remain supported, but new transport behavior belongs to
56
+ the shared protocol or the current sparse capsule path.
57
+
42
58
  ## Public identities
43
59
 
44
60
  Two lifecycle identities are central to the ordinary API:
@@ -21,12 +21,15 @@ shared exact dependencies:
21
21
  lean-runtime init MyProof
22
22
  cd MyProof
23
23
  lean-runtime check MyProof/Basic.lean
24
+ lean-runtime check
24
25
  lean-runtime build
25
26
  ```
26
27
 
27
28
  By default, `init` writes an `AGENTS.md` explaining the project workflow and
28
29
  shared-dependency safety rules to coding agents. Pass `--no-agents` to omit it.
29
- An existing file is preserved.
30
+ An existing file is preserved. The generated root imports only the project's
31
+ local `Basic` module; add the narrow Mathlib imports each implementation file
32
+ needs rather than paying for the all-Mathlib umbrella on every root import.
30
33
 
31
34
  Use `--mathlib 4.33.0` to select that release explicitly, or `--core` for a
32
35
  core-only library. The root project remains an ordinary mutable Lake project;
@@ -0,0 +1,154 @@
1
+ # Lake artifact-cache integration design
2
+
3
+ !!! note
4
+
5
+ The root-only local cache and project-wide check described below are
6
+ implemented. Remote mappings remain deliberately gated on strong artifact
7
+ verification and acquisition planning.
8
+
9
+ ## Ownership
10
+
11
+ Lean Runtime should complement the standard Lean tools rather than replace
12
+ their build semantics:
13
+
14
+ - Elan selects and installs the toolchain pinned by `lean-toolchain`.
15
+ - Lake resolves packages and owns targets, facets, traces, executables, custom
16
+ build logic, and complete project builds.
17
+ - Mathlib's cache supplies prebuilt upstream artifacts but does not cache a
18
+ downstream project's own outputs.
19
+ - Lake's artifact cache shares input- and content-addressed outputs between
20
+ workspaces using the same toolchain and can register remote mappings for lazy
21
+ restoration.
22
+ - Lean Runtime selects, verifies, distributes, and shares an exact environment
23
+ with provenance and download policy.
24
+
25
+ Consequently, Lean Runtime must not implement a second general-purpose Lake
26
+ target scheduler.
27
+
28
+ ## Public contract
29
+
30
+ The intended commands are:
31
+
32
+ ```text
33
+ lean-runtime check Foo.lean
34
+ lean-runtime check
35
+ lean-runtime build
36
+ ```
37
+
38
+ `check Foo.lean` remains the focused development loop. A file-less `check`
39
+ will check all local Lean modules without producing executables or native
40
+ libraries. `build` remains a complete Lake-compatible build of declared local
41
+ targets; it must not silently become a partial build.
42
+
43
+ ## Integration boundary
44
+
45
+ `ProjectExecutor` owns project command selection and execution policy. A future
46
+ `LakeArtifactCache` service should be injected into that executor and should
47
+ own only cache location, mappings, and restoration:
48
+
49
+ ```text
50
+ published OCI environment
51
+ ├── exact source and lock provenance
52
+ ├── sparse check capsule
53
+ └── Lake input-to-output mappings
54
+
55
+
56
+ toolchain-scoped Lake artifact cache
57
+
58
+
59
+ ProjectExecutor ─────► ordinary Lake target graph
60
+ ```
61
+
62
+ The cache directory must be keyed by the exact Lean toolchain identity and
63
+ platform ABI. It must never mix artifacts across incompatible toolchains.
64
+
65
+ ## Lake 4.33 experiment and decision
66
+
67
+ The experiment used one generated Mathlib 4.33 project and preserved the same
68
+ source and shared dependency graph for every measurement. The exact observed
69
+ interface is checked into `compatibility/lake-artifact-cache-4.33.0.json`.
70
+
71
+ Compare:
72
+
73
+ 1. the current bare Lake build through `lean-runtime build`;
74
+ 2. explicit root-package, local-library, root-module `leanArts`, and executable
75
+ targets;
76
+ 3. the same targets with `LAKE_ARTIFACT_CACHE=true` and a toolchain-scoped
77
+ `LAKE_CACHE_DIR`;
78
+ 4. the cache with publication mappings captured by `lake build -o` and
79
+ registered locally;
80
+ 5. warm process-cache and cold filesystem-cache runs.
81
+
82
+ The broad workspace cache was rejected: it copied about 6.5 GB of dependency
83
+ artifacts into a second cache and an explicit `@/Library:leanArts` target still
84
+ traversed 8,708 jobs. A root package with `enableArtifactCache = true`, combined
85
+ with workspace-level `LAKE_ARTIFACT_CACHE=false`, cached only root artifacts
86
+ (about 396 KB in the fixture) and restored them in about five seconds. This is
87
+ the implemented mode.
88
+
89
+ Support is detected from command behavior and help surfaces, not a parsed Lake
90
+ version. The verdict is cached by exact toolchain identity and platform ABI.
91
+ Verbose Lake output provides deterministic hit markers such as `restored
92
+ artifact from cache`; timing alone is not treated as proof of a hit.
93
+
94
+ ## Publication and acquisition
95
+
96
+ When the remaining integrity and performance gates succeed, environment publication should run the ordinary
97
+ verified build with a Lake mappings output. Publication should bind the mapping
98
+ digest to the same exact source revision, complete Lake graph, toolchain, and
99
+ platform record as the capsule.
100
+
101
+ Acquisition should:
102
+
103
+ 1. verify the environment and mapping descriptors through the existing OCI
104
+ trust path;
105
+ 2. install compatible artifacts into the toolchain-scoped Lake cache or add
106
+ mappings that point to a configured remote service;
107
+ 3. leave Lake responsible for evaluating input traces and restoring outputs;
108
+ 4. fail explicitly on corrupt mappings or artifacts instead of silently
109
+ treating them as verified environment content;
110
+ 5. permit an ordinary source build when policy allows it.
111
+
112
+ Lake recomputes its artifact hash after a remote fetch, but that hash is not a
113
+ cryptographic integrity boundary. Lean Runtime therefore does not currently
114
+ register remote mappings. A future remote adapter must bind a SHA-256 artifact
115
+ inventory into the verified OCI record, verify every restored artifact, emit
116
+ `acquisition.planned`, and charge all bytes against `max_download_bytes` before
117
+ registration. Until then, remote object storage would be inside the trust
118
+ boundary and is rejected.
119
+
120
+ OCI remains the environment and provenance distribution format. Lake's cache
121
+ format remains the build-cache contract. Translation between them belongs in a
122
+ small adapter, not in capsule, registry, or project CLI code.
123
+
124
+ ## Performance gate
125
+
126
+ The slice ships only if the same empty Mathlib project satisfies:
127
+
128
+ | Journey | Budget |
129
+ | --- | ---: |
130
+ | Focused warm file check | at most 3 seconds |
131
+ | Project-wide check | at most 10 seconds |
132
+ | First build with shared cache ready | at most 10 seconds |
133
+ | Warm no-op build | at most 3 seconds |
134
+ | Executable build | comparable to native Lake |
135
+ | Custom facet | handled unchanged by Lake |
136
+
137
+ Correctness gates must include libraries, executables, multiple local modules,
138
+ custom Lean options, Mathlib plus LeanCert, a supported custom facet, an
139
+ unsupported cache entry, corrupted cache content, and concurrent projects using
140
+ the same cache.
141
+
142
+ The scheduled compatibility workflow runs the root-cache correctness and
143
+ timing gate on macOS ARM and Linux x86. It verifies a first check, a warm check,
144
+ and restoration after removing the checkout-local build directory. Ordinary CI
145
+ also exercises toolchain/ABI key separation on both platforms. The cache does
146
+ not participate in the focused `lake env lean` path; that path consumes already
147
+ available imports directly.
148
+
149
+ Explicit targets and the native cache did not remove dependency-graph
150
+ traversal. The implemented fileless `check` therefore asks Lake to build only
151
+ local library `leanArts` facets, preserving correct intra-project ordering. The
152
+ next performance step is an opaque-prebuilt-dependency optimization in Lake.
153
+ A specialized local-module scheduler remains a last resort and would be called
154
+ `check`, never `build`.
@@ -46,12 +46,29 @@ each repository's `.lake/packages`. New projects can start in shared mode:
46
46
  lean-runtime init MyProof
47
47
  cd MyProof
48
48
  lean-runtime check MyProof/Basic.lean
49
+ lean-runtime check
49
50
  lean-runtime build
50
51
  ```
51
52
 
53
+ The fileless form asks Lake for the project's declared local libraries and
54
+ builds their `leanArts` facets. Lake therefore expands roots and submodules,
55
+ orders local imports, and creates any intermediate local `.olean` files; Lean
56
+ Runtime does not parse module globs or implement a second build scheduler. It
57
+ does not request executable or native-library targets. The Python equivalent is
58
+ `Runtime().project(".").check_all()`.
59
+
60
+ Projects created by `init` on a supported Lake also opt their root package into
61
+ Lake's native artifact cache. Lean Runtime capability-probes the resolved Lake executable
62
+ once, stores the result per exact toolchain and platform ABI, and otherwise
63
+ stays silent. Only root-project outputs enter this cache: locked dependencies
64
+ continue to use the verified shared workspace, avoiding a second multi-gigabyte
65
+ copy. `build` retains Lake's complete target semantics.
66
+
52
67
  The generated files are a standard Lake project plus a small
53
68
  `lean-runtime.toml`. Root build outputs stay local; exact dependencies are
54
- shared. The newest stable cataloged Mathlib is selected by default. Select a
69
+ shared. The generated root imports only its local `Basic` module, leaving
70
+ implementation files free to select precise Mathlib modules. The newest stable
71
+ cataloged Mathlib is selected by default. Select a
55
72
  release with `--mathlib 4.33.0`, or use `--core` for a core-only library.
56
73
  `init` also creates an `AGENTS.md` describing the safe
57
74
  build and dependency workflow unless `--no-agents` is passed; it never
@@ -5,7 +5,6 @@ from __future__ import annotations
5
5
  import gzip
6
6
  import hashlib
7
7
  import io
8
- import json
9
8
  import os
10
9
  import re
11
10
  import shutil
@@ -38,6 +37,22 @@ from .events import EventEmitter
38
37
  from .lake import ROOT_MODULE
39
38
  from .lockfiles import EnvironmentLock, LockedPackage
40
39
  from .locking import FileLock
40
+ from .oci_protocol import (
41
+ INDEX_MEDIA_TYPE,
42
+ MANIFEST_MEDIA_TYPE,
43
+ )
44
+ from .oci_protocol import (
45
+ blob_descriptor_path as _blob_descriptor_path,
46
+ )
47
+ from .oci_protocol import (
48
+ descriptor_blob_path as _descriptor_blob_path,
49
+ )
50
+ from .oci_protocol import (
51
+ json_object as _json_object,
52
+ )
53
+ from .oci_protocol import (
54
+ require_media_type as _require_media_type,
55
+ )
41
56
  from .packs import (
42
57
  PACK_MEDIA_TYPE,
43
58
  SparsePack,
@@ -60,8 +75,6 @@ CAPSULE_BUNDLE_SCHEMA = "lean-runtime-oci-capsule/1"
60
75
  CONFIG_MEDIA_TYPE = "application/vnd.lean-runtime.environment.config.v1+json"
61
76
  CAPSULE_CONFIG_MEDIA_TYPE = "application/vnd.lean-runtime.capsule.config.v1+json+zstd"
62
77
  LAYER_MEDIA_TYPE = "application/vnd.lean-runtime.environment.layer.v1.tar+gzip"
63
- MANIFEST_MEDIA_TYPE = "application/vnd.oci.image.manifest.v1+json"
64
- INDEX_MEDIA_TYPE = "application/vnd.oci.image.index.v1+json"
65
78
  MAX_BUNDLE_BYTES = 20 * 1024**3
66
79
  MAX_FILES = 2_000_000
67
80
  SOURCE_TREE_INVENTORY = ".lean-runtime-source-tree.json"
@@ -84,18 +97,6 @@ class PortableCopyInfo:
84
97
  }
85
98
 
86
99
 
87
- def _digest(data: bytes) -> str:
88
- return "sha256:" + hashlib.sha256(data).hexdigest()
89
-
90
-
91
- def _digest_path(path: Path) -> str:
92
- digest = hashlib.sha256()
93
- with path.open("rb") as handle:
94
- for chunk in iter(lambda: handle.read(1024 * 1024), b""):
95
- digest.update(chunk)
96
- return "sha256:" + digest.hexdigest()
97
-
98
-
99
100
  def _capsule_config_bytes(value: Mapping[str, Any]) -> bytes:
100
101
  return zstandard.ZstdCompressor(level=10, write_checksum=True).compress(
101
102
  canonical_json_bytes(dict(value))
@@ -112,19 +113,6 @@ def _capsule_config_object(data: bytes) -> dict[str, Any]:
112
113
  return _json_object(decoded, "capsule config")
113
114
 
114
115
 
115
- def _blob_descriptor(data: bytes, media_type: str, **extra: Any) -> dict[str, Any]:
116
- return {"mediaType": media_type, "digest": _digest(data), "size": len(data), **extra}
117
-
118
-
119
- def _blob_descriptor_path(path: Path, media_type: str, **extra: Any) -> dict[str, Any]:
120
- return {
121
- "mediaType": media_type,
122
- "digest": _digest_path(path),
123
- "size": path.stat().st_size,
124
- **extra,
125
- }
126
-
127
-
128
116
  def _normalized_info(name: str, *, mode: int, kind: bytes = tarfile.REGTYPE) -> tarfile.TarInfo:
129
117
  info = tarfile.TarInfo(name)
130
118
  info.type = kind
@@ -245,43 +233,6 @@ def _write_oci_archive(entries: dict[str, Path], output: Path) -> None:
245
233
  archive.addfile(info, handle)
246
234
 
247
235
 
248
- def _json_object(data: bytes, label: str) -> dict[str, Any]:
249
- try:
250
- value = json.loads(data)
251
- except (UnicodeDecodeError, json.JSONDecodeError) as exc:
252
- raise EnvironmentError(f"bundle {label} is not valid JSON") from exc
253
- if not isinstance(value, dict):
254
- raise EnvironmentError(f"bundle {label} must be a JSON object")
255
- return value
256
-
257
-
258
- def _descriptor_blob(entries: dict[str, bytes], descriptor: dict[str, Any], label: str) -> bytes:
259
- digest = descriptor.get("digest")
260
- size = descriptor.get("size")
261
- if not isinstance(digest, str) or not digest.startswith("sha256:"):
262
- raise EnvironmentError(f"bundle {label} has an invalid digest")
263
- data = entries.get("blobs/sha256/" + digest.removeprefix("sha256:"))
264
- if data is None or len(data) != size or _digest(data) != digest:
265
- raise EnvironmentError(f"bundle {label} digest mismatch")
266
- return data
267
-
268
-
269
- def _descriptor_blob_path(entries: dict[str, Path], descriptor: dict[str, Any], label: str) -> Path:
270
- digest = descriptor.get("digest")
271
- size = descriptor.get("size")
272
- if not isinstance(digest, str) or not digest.startswith("sha256:"):
273
- raise EnvironmentError(f"bundle {label} has an invalid digest")
274
- path = entries.get("blobs/sha256/" + digest.removeprefix("sha256:"))
275
- if path is None or path.stat().st_size != size or _digest_path(path) != digest:
276
- raise EnvironmentError(f"bundle {label} digest mismatch")
277
- return path
278
-
279
-
280
- def _require_media_type(descriptor: dict[str, Any], expected: str, label: str) -> None:
281
- if descriptor.get("mediaType") != expected:
282
- raise EnvironmentError(f"bundle {label} has an unsupported media type")
283
-
284
-
285
236
  def _safe_name(name: str) -> PurePosixPath:
286
237
  path = PurePosixPath(name)
287
238
  if (
@@ -248,14 +248,32 @@ def _cli_source_name(path: Path) -> str:
248
248
  return path.as_posix()
249
249
 
250
250
 
251
- def _emit_result(result: ExecutionResult, as_json: bool) -> None:
251
+ def _display_result_text(text: str, result: ExecutionResult, display_path: str | None) -> str:
252
+ """Rewrite only the staged entrypoint when the CLI has a logical input name."""
253
+ if display_path is None or not result.command:
254
+ return text
255
+ staged = result.command[-1]
256
+ candidates = {staged}
257
+ staged_path = Path(staged)
258
+ if not staged_path.is_absolute():
259
+ candidates.add(str(Path(result.cwd) / staged_path))
260
+ for candidate in sorted(candidates, key=len, reverse=True):
261
+ text = text.replace(candidate, display_path)
262
+ return text
263
+
264
+
265
+ def _emit_result(
266
+ result: ExecutionResult, as_json: bool, *, display_path: str | None = None
267
+ ) -> None:
252
268
  if as_json:
253
269
  _json(serialize_execution_v1(result))
254
270
  return
255
271
  if result.stdout:
256
- print(result.stdout, end="" if result.stdout.endswith("\n") else "\n")
272
+ stdout = _display_result_text(result.stdout, result, display_path)
273
+ print(stdout, end="" if stdout.endswith("\n") else "\n")
257
274
  if result.stderr:
258
- print(result.stderr, end="" if result.stderr.endswith("\n") else "\n", file=sys.stderr)
275
+ stderr = _display_result_text(result.stderr, result, display_path)
276
+ print(stderr, end="" if stderr.endswith("\n") else "\n", file=sys.stderr)
259
277
  status = "accepted" if result.ok else "rejected"
260
278
  environment = f" environment={result.environment_id}" if result.environment_id else ""
261
279
  print(
@@ -435,11 +453,11 @@ def parser() -> argparse.ArgumentParser:
435
453
  program_index.add_argument("--tag", action="append", default=[])
436
454
  program_index.add_argument("--sign", action="store_true")
437
455
 
438
- check = commands.add_parser("check", help="check one Lean file in its exact context")
456
+ check = commands.add_parser("check", help="check one Lean file or all local libraries")
439
457
  check.add_argument(
440
458
  "inputs",
441
- nargs="+",
442
- help="FILE, or legacy ENVIRONMENT FILE; FILE may be - for stdin",
459
+ nargs="*",
460
+ help="FILE, legacy ENVIRONMENT FILE, or omit inside a Lake project; FILE may be -",
443
461
  )
444
462
  check.add_argument(
445
463
  "--with",
@@ -450,7 +468,9 @@ def parser() -> argparse.ArgumentParser:
450
468
  help="repeatable github:owner/repository@tag-or-commit package reference",
451
469
  )
452
470
  check.add_argument("--toolchain", help="override the discovered file or package toolchain")
453
- check.add_argument("--project", type=Path, help="explicit Lake project for FILE")
471
+ check.add_argument(
472
+ "--project", type=Path, help="explicit Lake project for FILE or project-wide check"
473
+ )
454
474
  check.add_argument(
455
475
  "--include", action="append", default=[], type=Path, help="additional Lean source file"
456
476
  )
@@ -656,6 +676,7 @@ def parser() -> argparse.ArgumentParser:
656
676
  def main(argv: list[str] | None = None) -> int:
657
677
  args = parser().parse_args(argv)
658
678
  operation_started = time.monotonic()
679
+ display_path: str | None = None
659
680
  try:
660
681
  selected_availability = (
661
682
  "local" if args.command in {"init", "update"} and args.offline else args.availability
@@ -712,7 +733,10 @@ def main(argv: list[str] | None = None) -> int:
712
733
  print(f"Shared packages: {init_result.packages}")
713
734
  if args.agents:
714
735
  print(f"Agent guide: {init_result.root / 'AGENTS.md'}")
715
- print(f"Next: cd {init_result.root} && lean-runtime build")
736
+ project_name = init_plan.project_name or init_result.root.name
737
+ print(
738
+ f"Next: cd {init_result.root} && lean-runtime check {project_name}/Basic.lean"
739
+ )
716
740
  return 0
717
741
  if args.command == "scan":
718
742
  scan_result = runtime.scan_projects(args.path, recursive=args.recursive)
@@ -859,7 +883,7 @@ def main(argv: list[str] | None = None) -> int:
859
883
  print(f"Created {output}")
860
884
  return 0
861
885
  if args.command == "install":
862
- print(runtime.toolchains.ensure(args.toolchain))
886
+ print(runtime.toolchains.ensure_full(args.toolchain))
863
887
  return 0
864
888
  if args.command == "prepare":
865
889
  lock = runtime.prepare(EnvironmentSpec.load(args.spec), timeout=args.timeout)
@@ -1195,7 +1219,14 @@ def main(argv: list[str] | None = None) -> int:
1195
1219
  if args.command == "check":
1196
1220
  if args.project is not None and args.package_refs:
1197
1221
  raise ValueError("check cannot combine --project with --with")
1198
- if args.package_refs:
1222
+ if not args.inputs:
1223
+ if args.package_refs or args.include:
1224
+ raise ValueError("project-wide check does not accept --with or --include")
1225
+ result = runtime.check_project(
1226
+ args.project or Path("."), toolchain=args.toolchain, policy=_policy(args)
1227
+ )
1228
+ source_file = None
1229
+ elif args.package_refs:
1199
1230
  if len(args.inputs) != 1:
1200
1231
  raise ValueError("check with --with expects exactly one FILE")
1201
1232
  environment = runtime.open_references(args.package_refs, toolchain=args.toolchain)
@@ -1205,6 +1236,7 @@ def main(argv: list[str] | None = None) -> int:
1205
1236
  raise ValueError("local project checks do not accept --include")
1206
1237
  source_file = Path(args.inputs[0])
1207
1238
  if str(source_file) == "-":
1239
+ display_path = "<stdin>"
1208
1240
  result = runtime.check(
1209
1241
  sys.stdin.read(),
1210
1242
  toolchain=args.toolchain,
@@ -1244,6 +1276,7 @@ def main(argv: list[str] | None = None) -> int:
1244
1276
  )
1245
1277
  elif args.command == "check-file":
1246
1278
  if str(args.file) == "-":
1279
+ display_path = "<stdin>"
1247
1280
  result = runtime.check(
1248
1281
  sys.stdin.read(),
1249
1282
  toolchain=args.toolchain,
@@ -1300,7 +1333,7 @@ def main(argv: list[str] | None = None) -> int:
1300
1333
  else:
1301
1334
  print(f"lean-runtime: {exc}", file=sys.stderr)
1302
1335
  return 2
1303
- _emit_result(result, args.json)
1336
+ _emit_result(result, args.json, display_path=display_path)
1304
1337
  if args.timings:
1305
1338
  print(render_timings(result.timings), file=sys.stderr)
1306
1339
  return 0 if result.ok else 1