lean-runtime 2.5.0__tar.gz → 2.6.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 (171) hide show
  1. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/CHANGELOG.md +19 -0
  2. {lean_runtime-2.5.0/lean_runtime.egg-info → lean_runtime-2.6.0}/PKG-INFO +17 -14
  3. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/README.md +16 -13
  4. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/docs/cli.md +16 -9
  5. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/docs/getting-started.md +30 -13
  6. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/docs/local-projects.md +34 -7
  7. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/__init__.py +6 -0
  8. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/cli.py +169 -16
  9. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/models.py +1 -0
  10. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/project_sharing.py +91 -0
  11. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/projects.py +46 -1
  12. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/runtime.py +566 -132
  13. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/shared_projects.py +146 -1
  14. {lean_runtime-2.5.0 → lean_runtime-2.6.0/lean_runtime.egg-info}/PKG-INFO +17 -14
  15. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/pyproject.toml +1 -1
  16. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/tests/test_cli.py +35 -0
  17. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/tests/test_projects.py +254 -6
  18. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/LICENSE +0 -0
  19. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/MANIFEST.in +0 -0
  20. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/catalog/environments.toml +0 -0
  21. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/catalog/locks/core-v4.32.2.lock.json +0 -0
  22. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/catalog/locks/leancert-v4.30.0.5.lock.json +0 -0
  23. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/catalog/locks/leancert-v4.31.0.lock.json +0 -0
  24. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/catalog/locks/leancert-v4.32.2.4.lock.json +0 -0
  25. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/catalog/locks/leancert-v4.33.0.lock.json +0 -0
  26. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/catalog/locks/mathlib-v4.30.0.lock.json +0 -0
  27. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/catalog/locks/mathlib-v4.31.0.lock.json +0 -0
  28. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/catalog/locks/mathlib-v4.32.2.lock.json +0 -0
  29. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/catalog/locks/mathlib-v4.33.0.lock.json +0 -0
  30. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/compatibility/README.md +0 -0
  31. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/compatibility/mathlib-4.32.2.json +0 -0
  32. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/compatibility/mathlib-4.32.2.toml +0 -0
  33. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/compatibility/mathlib-4.33.0.json +0 -0
  34. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/compatibility/mathlib-4.33.0.toml +0 -0
  35. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/docs/architecture.md +0 -0
  36. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/docs/captures.md +0 -0
  37. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/docs/case-study-v1.md +0 -0
  38. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/docs/development.md +0 -0
  39. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/docs/environments.md +0 -0
  40. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/docs/index.md +0 -0
  41. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/docs/portable-copies.md +0 -0
  42. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/docs/project-publishing.md +0 -0
  43. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/docs/python-api.md +0 -0
  44. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/docs/ready-programs.md +0 -0
  45. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/docs/standalone-files.md +0 -0
  46. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/docs/trust-and-limitations.md +0 -0
  47. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/docs/v1-precision.md +0 -0
  48. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/examples/mathlib.toml +0 -0
  49. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/__main__.py +0 -0
  50. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/_git.py +0 -0
  51. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/_paths.py +0 -0
  52. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/backends.py +0 -0
  53. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/bundles.py +0 -0
  54. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/capsules.py +0 -0
  55. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/comparison.py +0 -0
  56. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/console.py +0 -0
  57. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/decisions.py +0 -0
  58. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/diagnostics.py +0 -0
  59. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/discovery/__init__.py +0 -0
  60. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/discovery/analyzer.py +0 -0
  61. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/discovery/api.py +0 -0
  62. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/discovery/candidate.py +0 -0
  63. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/discovery/catalog.py +0 -0
  64. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/discovery/catalog_build.py +0 -0
  65. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/discovery/catalog_cli.py +0 -0
  66. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/discovery/catalog_manifest.py +0 -0
  67. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/discovery/data/catalog.json +0 -0
  68. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/discovery/defaults.py +0 -0
  69. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/discovery/engine.py +0 -0
  70. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/discovery/errors.py +0 -0
  71. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/discovery/module_inventory.py +0 -0
  72. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/discovery/planner.py +0 -0
  73. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/discovery/policy.py +0 -0
  74. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/discovery/probe.py +0 -0
  75. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/discovery/py.typed +0 -0
  76. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/discovery/result.py +0 -0
  77. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/discovery/schema_resources.py +0 -0
  78. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/discovery/schemas/catalog-v1.schema.json +0 -0
  79. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/discovery/schemas/plan-v1.schema.json +0 -0
  80. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/discovery/schemas/result-v1.schema.json +0 -0
  81. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/environments.py +0 -0
  82. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/errors.py +0 -0
  83. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/events.py +0 -0
  84. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/facade.py +0 -0
  85. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/frontmatter.py +0 -0
  86. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/health.py +0 -0
  87. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/lake.py +0 -0
  88. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/lockfiles.py +0 -0
  89. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/locking.py +0 -0
  90. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/matrix.py +0 -0
  91. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/oci.py +0 -0
  92. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/packs.py +0 -0
  93. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/policies.py +0 -0
  94. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/profiling.py +0 -0
  95. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/programs.py +0 -0
  96. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/publisher_verification.py +0 -0
  97. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/py.typed +0 -0
  98. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/references.py +0 -0
  99. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/resolver.py +0 -0
  100. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/run_cli.py +0 -0
  101. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/schema_resources.py +0 -0
  102. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/serialization.py +0 -0
  103. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/specs.py +0 -0
  104. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/store.py +0 -0
  105. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/timings.py +0 -0
  106. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/toolchain_oci.py +0 -0
  107. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/toolchain_slim.py +0 -0
  108. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/toolchains.py +0 -0
  109. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/verification.py +0 -0
  110. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime/wire.py +0 -0
  111. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime.egg-info/SOURCES.txt +0 -0
  112. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime.egg-info/dependency_links.txt +0 -0
  113. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime.egg-info/entry_points.txt +0 -0
  114. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime.egg-info/requires.txt +0 -0
  115. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/lean_runtime.egg-info/top_level.txt +0 -0
  116. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/mkdocs.yml +0 -0
  117. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/schemas/cleanup-v1.schema.json +0 -0
  118. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/schemas/comparison-v1.schema.json +0 -0
  119. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/schemas/execution-v1.schema.json +0 -0
  120. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/schemas/inspect-v1.schema.json +0 -0
  121. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/schemas/matrix-v1.schema.json +0 -0
  122. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/schemas/profile-v1.schema.json +0 -0
  123. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/schemas/verify-v1.schema.json +0 -0
  124. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/scripts/announcement_gate.py +0 -0
  125. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/scripts/registry_preflight.py +0 -0
  126. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/scripts/run_compatibility.py +0 -0
  127. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/scripts/run_v1_case_study.py +0 -0
  128. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/scripts/smoke_wheel.py +0 -0
  129. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/setup.cfg +0 -0
  130. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/tests/conftest.py +0 -0
  131. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/tests/discovery/e2e/test_real_discovery.py +0 -0
  132. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/tests/discovery/test_analyzer.py +0 -0
  133. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/tests/discovery/test_catalog.py +0 -0
  134. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/tests/discovery/test_catalog_build.py +0 -0
  135. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/tests/discovery/test_discovery_schema_resources.py +0 -0
  136. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/tests/discovery/test_engine.py +0 -0
  137. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/tests/discovery/test_planner.py +0 -0
  138. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/tests/discovery/test_policy.py +0 -0
  139. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/tests/test_backend.py +0 -0
  140. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/tests/test_bundles.py +0 -0
  141. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/tests/test_capsules.py +0 -0
  142. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/tests/test_console.py +0 -0
  143. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/tests/test_diagnostics.py +0 -0
  144. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/tests/test_environment_integration.py +0 -0
  145. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/tests/test_events_health.py +0 -0
  146. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/tests/test_facade.py +0 -0
  147. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/tests/test_frontmatter.py +0 -0
  148. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/tests/test_git.py +0 -0
  149. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/tests/test_interactive.py +0 -0
  150. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/tests/test_lockfiles.py +0 -0
  151. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/tests/test_models.py +0 -0
  152. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/tests/test_multifile.py +0 -0
  153. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/tests/test_packs.py +0 -0
  154. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/tests/test_paths.py +0 -0
  155. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/tests/test_prebuilt_policy.py +0 -0
  156. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/tests/test_programs.py +0 -0
  157. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/tests/test_project_publish.py +0 -0
  158. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/tests/test_references.py +0 -0
  159. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/tests/test_run_cli.py +0 -0
  160. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/tests/test_runtime.py +0 -0
  161. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/tests/test_schema_resources.py +0 -0
  162. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/tests/test_schemas.py +0 -0
  163. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/tests/test_signatures.py +0 -0
  164. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/tests/test_specs.py +0 -0
  165. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/tests/test_store.py +0 -0
  166. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/tests/test_toolchain_oci.py +0 -0
  167. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/tests/test_toolchain_slim.py +0 -0
  168. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/tests/test_toolchains.py +0 -0
  169. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/tests/test_v1_precision.py +0 -0
  170. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/tests/test_verification_inventory.py +0 -0
  171. {lean_runtime-2.5.0 → lean_runtime-2.6.0}/tests/test_verification_probe.py +0 -0
@@ -2,6 +2,25 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 2.6.0 - 2026-08-14
6
+
7
+ - Make the local-project path a four-command workflow: `init`, `check`,
8
+ `build`, and `update`. New projects use the newest stable cataloged Mathlib
9
+ by default; `--core` opts out, while `--mathlib VERSION` selects a release.
10
+ - Make `init` adopt an existing pinned Lake project without changing its graph,
11
+ or create a new project transactionally after its exact dependencies are
12
+ ready. `--plan`, `--offline`, `--max-download`, and `--seed-from` expose its
13
+ acquisition policy, and failed initialization leaves no partial project.
14
+ - Add persistent discovery of exact local Lake graphs. `scan` registers existing
15
+ projects as zero-download seeds for future initialization and updates.
16
+ - Preserve verified sparse-capsule build artifacts when materializing exact Git
17
+ sources for a mutable project, instead of throwing them away and forcing a
18
+ dependency rebuild.
19
+ - Add explicit, transactional `update` to the newest cataloged Mathlib, with an
20
+ old/new revision and toolchain preview and rollback after failed adoption.
21
+ - Include exact package revisions, Git tree hashes, and the shared workspace ID
22
+ in mutable-project check and build provenance.
23
+
5
24
  ## 2.5.0 - 2026-08-14
6
25
 
7
26
  - Make `lean-runtime init` create a concise `AGENTS.md` with build, checking,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lean-runtime
3
- Version: 2.5.0
3
+ Version: 2.6.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
@@ -181,31 +181,34 @@ project = lean.setup(project="./my-project")
181
181
  result = project.check_file("./my-project/MyProject/Main.lean")
182
182
  ```
183
183
 
184
- Create a normal Lake project whose exact dependencies are shared automatically:
184
+ Create a normal Lake project. The newest stable cataloged Mathlib is the
185
+ default, and exact dependencies are shared automatically:
185
186
 
186
187
  ```bash
187
- lean-runtime init MyProof --mathlib
188
+ lean-runtime init MyProof
188
189
  cd MyProof
189
- lean-runtime build .
190
+ lean-runtime check MyProof/Basic.lean
191
+ lean-runtime build
190
192
  ```
191
193
 
192
194
  `init` also writes an `AGENTS.md` with the project build, checking, dependency,
193
195
  and shared-package rules for coding agents. Pass `--no-agents` to omit it; an
194
- existing `AGENTS.md` is never overwritten.
196
+ existing `AGENTS.md` is never overwritten. Use `--core` for no Mathlib, or
197
+ `--mathlib 4.33.0` to select a cataloged release. `lean-runtime update`
198
+ explicitly moves a project to the newest cataloged Mathlib after a preview.
195
199
 
196
- Existing repositories can preview and adopt the same layout individually or in
197
- bulk:
200
+ Running `lean-runtime init .` in an existing pinned Lake project adopts its
201
+ current exact graph without running `lake update`. If you already have many
202
+ Lake checkouts, register them once as local dependency seeds:
198
203
 
199
204
  ```bash
200
- lean-runtime attach ~/research --recursive
201
- lean-runtime attach ~/research --recursive --execute
205
+ lean-runtime scan ~/research
206
+ lean-runtime init .
202
207
  ```
203
208
 
204
- The dry run reports blockers and estimated recovery without changing anything.
205
- Adoption preserves each root `.lake/build`, verifies both the override and
206
- ordinary Lake views, then replaces only generated package copies with links to
207
- the content-addressed store. `lean-runtime detach . --execute` materializes an
208
- independent project again.
209
+ `init --plan` is side-effect free; `--max-download 500MiB` and `--offline`
210
+ enforce cold-start policy. Advanced bulk migration remains available through
211
+ `attach`, and `detach --execute` materializes an independent project again.
209
212
 
210
213
  One-shot helpers are available when setup reuse is unnecessary:
211
214
 
@@ -145,31 +145,34 @@ project = lean.setup(project="./my-project")
145
145
  result = project.check_file("./my-project/MyProject/Main.lean")
146
146
  ```
147
147
 
148
- Create a normal Lake project whose exact dependencies are shared automatically:
148
+ Create a normal Lake project. The newest stable cataloged Mathlib is the
149
+ default, and exact dependencies are shared automatically:
149
150
 
150
151
  ```bash
151
- lean-runtime init MyProof --mathlib
152
+ lean-runtime init MyProof
152
153
  cd MyProof
153
- lean-runtime build .
154
+ lean-runtime check MyProof/Basic.lean
155
+ lean-runtime build
154
156
  ```
155
157
 
156
158
  `init` also writes an `AGENTS.md` with the project build, checking, dependency,
157
159
  and shared-package rules for coding agents. Pass `--no-agents` to omit it; an
158
- existing `AGENTS.md` is never overwritten.
160
+ existing `AGENTS.md` is never overwritten. Use `--core` for no Mathlib, or
161
+ `--mathlib 4.33.0` to select a cataloged release. `lean-runtime update`
162
+ explicitly moves a project to the newest cataloged Mathlib after a preview.
159
163
 
160
- Existing repositories can preview and adopt the same layout individually or in
161
- bulk:
164
+ Running `lean-runtime init .` in an existing pinned Lake project adopts its
165
+ current exact graph without running `lake update`. If you already have many
166
+ Lake checkouts, register them once as local dependency seeds:
162
167
 
163
168
  ```bash
164
- lean-runtime attach ~/research --recursive
165
- lean-runtime attach ~/research --recursive --execute
169
+ lean-runtime scan ~/research
170
+ lean-runtime init .
166
171
  ```
167
172
 
168
- The dry run reports blockers and estimated recovery without changing anything.
169
- Adoption preserves each root `.lake/build`, verifies both the override and
170
- ordinary Lake views, then replaces only generated package copies with links to
171
- the content-addressed store. `lean-runtime detach . --execute` materializes an
172
- independent project again.
173
+ `init --plan` is side-effect free; `--max-download 500MiB` and `--offline`
174
+ enforce cold-start policy. Advanced bulk migration remains available through
175
+ `attach`, and `detach --execute` materializes an independent project again.
173
176
 
174
177
  One-shot helpers are available when setup reuse is unnecessary:
175
178
 
@@ -146,25 +146,32 @@ environment can replay offline.
146
146
  ## Existing projects and core Lean
147
147
 
148
148
  ```bash
149
- lean-runtime check-file Main.lean --toolchain 4.32.2
150
- lean-runtime check-file ./existing-project/MyProject/Main.lean
151
- lean-runtime build ./existing-project MyLibrary
152
- lean-runtime init MyProof --mathlib
153
- lean-runtime init MyProof --mathlib --no-agents
149
+ lean-runtime check Main.lean --toolchain 4.32.2
150
+ lean-runtime check ./existing-project/MyProject/Main.lean
151
+ lean-runtime build
152
+ lean-runtime init MyProof
153
+ lean-runtime init MyProof --core
154
+ lean-runtime init --plan --max-download 500MiB
155
+ lean-runtime update --plan
156
+ lean-runtime scan ~/research
154
157
  lean-runtime attach ~/research --recursive
155
158
  lean-runtime attach ~/research --recursive --execute
156
159
  lean-runtime detach ./existing-project --execute
157
160
  lean-runtime install 4.32.2
158
161
  ```
159
162
 
160
- Without `--with`, the environment-aware `check` command requires an environment
161
- identifier. `check-file` is the direct local-project route. When no
163
+ `check FILE` is the direct standalone/local-project route; the legacy
164
+ `check ENVIRONMENT FILE` spelling remains accepted. When no
162
165
  `--project` or `--toolchain` is supplied, it discovers the nearest directory
163
166
  containing a Lake configuration and `lean-toolchain`, then passes the actual
164
167
  project-relative file to `lake env lean`.
165
168
 
166
- `init` creates a standard core or Mathlib Lake library and attaches its exact
167
- cataloged dependencies. `attach` is read-only unless `--execute` is present;
169
+ `init` defaults to the newest stable cataloged Mathlib, or adopts an existing
170
+ pinned Lake project without changing its graph. `--core` opts out of Mathlib.
171
+ It prepares dependencies before atomically publishing a new project. `update`
172
+ is the explicit transactional move to the newest cataloged Mathlib; `scan`
173
+ records exact existing graphs as future local seeds. `attach` is read-only
174
+ unless `--execute` is present;
168
175
  recursive mode inventories a project tree, reports blockers and estimated disk
169
176
  recovery, and adopts each valid project transactionally. `detach` is likewise a
170
177
  preview unless `--execute` is present. Attached projects use shared mode by
@@ -18,33 +18,50 @@ Create a standard Lake library with the newest cataloged Mathlib release and
18
18
  shared exact dependencies:
19
19
 
20
20
  ```bash
21
- lean-runtime init MyProof --mathlib
21
+ lean-runtime init MyProof
22
22
  cd MyProof
23
- lean-runtime build .
23
+ lean-runtime check MyProof/Basic.lean
24
+ lean-runtime build
24
25
  ```
25
26
 
26
27
  By default, `init` writes an `AGENTS.md` explaining the project workflow and
27
28
  shared-dependency safety rules to coding agents. Pass `--no-agents` to omit it.
28
29
  An existing file is preserved.
29
30
 
30
- Use `--mathlib 4.33.0` to select that release explicitly. Omit `--mathlib` for
31
- a core-only library. The root project remains an ordinary mutable Lake project;
31
+ Use `--mathlib 4.33.0` to select that release explicitly, or `--core` for a
32
+ core-only library. The root project remains an ordinary mutable Lake project;
32
33
  its dependency sources and build artifacts are reused by other projects with
33
34
  the same exact graph.
34
35
 
35
- For an existing project or a directory containing many projects, preview the
36
- migration before applying it:
36
+ Before doing any work, `init --plan` reports the exact release, local reuse, and
37
+ known download size. `--max-download 500MiB` refuses a larger transfer and
38
+ `--offline` requires a matching local graph. Initialization is transactional:
39
+ the target appears only after Lake and the shared dependency graph both verify.
40
+ Project development requires one full Lake-capable Lean toolchain per Lean
41
+ version. When it is absent, the plan says its Elan download size is unknown;
42
+ `--offline` and `--max-download` fail closed instead of silently installing it.
43
+
44
+ Dependency upgrades are explicit:
45
+
46
+ ```bash
47
+ lean-runtime update --plan
48
+ lean-runtime update
49
+ ```
50
+
51
+ The update preview names both exact Mathlib revisions and toolchains. In a
52
+ terminal, the second command asks for confirmation; use `--yes` in automation.
53
+
54
+ For one existing pinned Lake project, preserve and adopt its current exact graph:
37
55
 
38
56
  ```bash
39
- lean-runtime attach .
40
- lean-runtime attach ~/research --recursive
41
- lean-runtime attach ~/research --recursive --execute
57
+ lean-runtime init .
58
+ lean-runtime scan ~/research
42
59
  ```
43
60
 
44
- The first two commands are read-only. Execution verifies the shared graph,
45
- replaces only generated package copies, and rolls back the swap if ordinary
46
- Lake cannot load the result. See [Local Lake projects](local-projects.md) for
47
- detachment, storage estimates, and the complete safety model.
61
+ `scan` only records exact local graphs as possible future zero-download seeds.
62
+ Advanced bulk migration remains available through `attach`. See [Local Lake
63
+ projects](local-projects.md) for detachment, storage estimates, and the complete
64
+ safety model.
48
65
 
49
66
  ## Run a file
50
67
 
@@ -22,10 +22,10 @@ managed environment, dependency list, or explicit toolchain is supplied:
22
22
  result = Runtime().check_file("./my-project/MyProject/Main.lean")
23
23
  ```
24
24
 
25
- The CLI equivalent is:
25
+ The primary CLI equivalent is:
26
26
 
27
27
  ```bash
28
- lean-runtime check-file ./my-project/MyProject/Main.lean
28
+ lean-runtime check ./my-project/MyProject/Main.lean
29
29
  ```
30
30
 
31
31
  The actual project-relative file is passed to `lake env lean`, so imports of
@@ -43,19 +43,46 @@ Ordinary Lake workspaces put remote dependencies and their build artifacts in
43
43
  each repository's `.lake/packages`. New projects can start in shared mode:
44
44
 
45
45
  ```bash
46
- lean-runtime init MyProof --mathlib
46
+ lean-runtime init MyProof
47
47
  cd MyProof
48
- lean-runtime build .
48
+ lean-runtime check MyProof/Basic.lean
49
+ lean-runtime build
49
50
  ```
50
51
 
51
52
  The generated files are a standard Lake project plus a small
52
53
  `lean-runtime.toml`. Root build outputs stay local; exact dependencies are
53
- shared. Select a cataloged release with `--mathlib 4.33.0`, or omit `--mathlib`
54
- for a core-only library. `init` also creates an `AGENTS.md` describing the safe
54
+ shared. The newest stable cataloged Mathlib is selected by default. Select a
55
+ release with `--mathlib 4.33.0`, or use `--core` for a core-only library.
56
+ `init` also creates an `AGENTS.md` describing the safe
55
57
  build and dependency workflow unless `--no-agents` is passed; it never
56
58
  overwrites an existing guide.
57
59
 
58
- For one existing project, preview before changing anything:
60
+ Initialization acquires and verifies the exact graph before publishing the
61
+ target directory. Use `--plan` for a side-effect-free cost report, `--offline`
62
+ to require local data, `--max-download SIZE` to enforce a transfer ceiling, or
63
+ `--seed-from PROJECT` to name an exact local donor.
64
+ The plan separately reports whether the full Lake-capable toolchain is already
65
+ installed. Because Elan does not publish a preflight byte count, a missing full
66
+ toolchain is rejected under `--offline` or `--max-download` rather than silently
67
+ bypassing the policy.
68
+
69
+ For an existing pinned project, `lean-runtime init .` adopts its current
70
+ manifest without changing versions. Register a collection once with
71
+ `lean-runtime scan ~/research`; future exact matches are preferred over
72
+ downloads automatically.
73
+
74
+ Move an adopted TOML project to the newest cataloged Mathlib explicitly:
75
+
76
+ ```bash
77
+ lean-runtime update --plan
78
+ lean-runtime update
79
+ ```
80
+
81
+ The plan reports old and new release, commit, toolchain, local donor, and known
82
+ download bytes. Acquisition happens before metadata changes, and failures
83
+ restore the prior Lake files and attachment metadata.
84
+
85
+ For advanced bulk onboarding, preview before changing anything:
59
86
 
60
87
  ```bash
61
88
  lean-runtime attach .
@@ -59,6 +59,9 @@ from .project_sharing import (
59
59
  AdoptionResult,
60
60
  DetachmentPlan,
61
61
  ProjectAdoption,
62
+ ProjectInitPlan,
63
+ ProjectScanResult,
64
+ ProjectUpdatePlan,
62
65
  )
63
66
  from .projects import (
64
67
  ProjectContext,
@@ -85,6 +88,9 @@ __all__ = [
85
88
  "AdoptionPlan",
86
89
  "AdoptionResult",
87
90
  "DetachmentPlan",
91
+ "ProjectInitPlan",
92
+ "ProjectScanResult",
93
+ "ProjectUpdatePlan",
88
94
  "EnvironmentComparison",
89
95
  "ComparisonEntry",
90
96
  "PortableCopyInfo",
@@ -18,8 +18,8 @@ from .lake import ROOT_MODULE
18
18
  from .lockfiles import EnvironmentLock
19
19
  from .matrix import load_matrix
20
20
  from .models import ExecutionResult, PhaseTiming
21
- from .policies import ExecutionPolicy, format_byte_size
22
- from .project_sharing import AdoptionPlan
21
+ from .policies import ExecutionPolicy, format_byte_size, parse_byte_size
22
+ from .project_sharing import AdoptionPlan, ProjectInitPlan, ProjectUpdatePlan
23
23
  from .projects import discover_project, project_publication_workflow
24
24
  from .runtime import Runtime
25
25
  from .specs import EnvironmentSpec
@@ -177,6 +177,46 @@ def _render_adoption_plan(plan: AdoptionPlan) -> None:
177
177
  print(f"Potential recovery: {format_byte_size(plan.estimated_reclaimable_bytes)}")
178
178
 
179
179
 
180
+ def _render_init_plan(plan: ProjectInitPlan) -> None:
181
+ if plan.action == "adopt":
182
+ state = "already attached" if plan.already_attached else "ready to attach"
183
+ print(f"Existing Lake project · {plan.toolchain} · {state}")
184
+ print(f"Exact dependencies: {len(plan.packages)} package(s); versions unchanged")
185
+ return
186
+ context = f"Mathlib {plan.mathlib_version}" if plan.mathlib_version else "core Lean"
187
+ print(f"Create {plan.root.name} · {context} · {plan.toolchain}")
188
+ if not plan.toolchain_installed:
189
+ print("Full Lake toolchain: download required (size not published by Elan)")
190
+ if plan.seed_root is not None:
191
+ print(f"Reuse exact local graph: {plan.seed_root}")
192
+ print("Download: 0 B")
193
+ elif plan.download_bytes is not None:
194
+ print(f"Download: {format_byte_size(plan.download_bytes)}")
195
+ else:
196
+ print("Download: unknown (no compatible published artifact could be priced)")
197
+
198
+
199
+ def _render_update_plan(plan: ProjectUpdatePlan) -> None:
200
+ if not plan.changed:
201
+ print(f"Already current: Mathlib {plan.target_version} · {plan.target_toolchain}")
202
+ return
203
+ print(
204
+ f"Mathlib {plan.current_version} → {plan.target_version} · "
205
+ f"{plan.current_toolchain} → {plan.target_toolchain}"
206
+ )
207
+ if not plan.toolchain_installed:
208
+ print("Full Lake toolchain: download required (size not published by Elan)")
209
+ if plan.seed_root is not None:
210
+ print(f"Reuse exact local graph: {plan.seed_root}")
211
+ print("Download: 0 B")
212
+ elif plan.download_bytes is not None:
213
+ print(f"Download: {format_byte_size(plan.download_bytes)}")
214
+ else:
215
+ print("Download: unknown")
216
+ for blocker in plan.blockers:
217
+ print(f"Blocker: {blocker}")
218
+
219
+
180
220
  def _progress(event: RuntimeEvent) -> None:
181
221
  package = f" [{event.data['package']}]" if "package" in event.data else ""
182
222
  print(f"lean-runtime: {event.kind}{package}: {event.message}", file=sys.stderr)
@@ -383,13 +423,11 @@ def parser() -> argparse.ArgumentParser:
383
423
  program_index.add_argument("--tag", action="append", default=[])
384
424
  program_index.add_argument("--sign", action="store_true")
385
425
 
386
- check = commands.add_parser(
387
- "check", help="check with --with packages or in a published environment"
388
- )
426
+ check = commands.add_parser("check", help="check one Lean file in its exact context")
389
427
  check.add_argument(
390
428
  "inputs",
391
429
  nargs="+",
392
- help="FILE with --with, otherwise ENVIRONMENT FILE; FILE may be - for stdin",
430
+ help="FILE, or legacy ENVIRONMENT FILE; FILE may be - for stdin",
393
431
  )
394
432
  check.add_argument(
395
433
  "--with",
@@ -399,7 +437,8 @@ def parser() -> argparse.ArgumentParser:
399
437
  metavar="REFERENCE",
400
438
  help="repeatable github:owner/repository@tag-or-commit package reference",
401
439
  )
402
- check.add_argument("--toolchain", help="override the toolchain discovered from --with packages")
440
+ check.add_argument("--toolchain", help="override the discovered file or package toolchain")
441
+ check.add_argument("--project", type=Path, help="explicit Lake project for FILE")
403
442
  check.add_argument(
404
443
  "--include", action="append", default=[], type=Path, help="additional Lean source file"
405
444
  )
@@ -475,7 +514,7 @@ def parser() -> argparse.ArgumentParser:
475
514
  _add_policy(raw)
476
515
 
477
516
  build = commands.add_parser("build", help="build an existing Lake project")
478
- build.add_argument("project", type=Path)
517
+ build.add_argument("project", type=Path, nargs="?", default=Path("."))
479
518
  build.add_argument("targets", nargs="*")
480
519
  build.add_argument("--toolchain")
481
520
  build.add_argument("--timeout", type=float, default=900)
@@ -495,15 +534,30 @@ def parser() -> argparse.ArgumentParser:
495
534
  )
496
535
  build.add_argument("--json", action="store_true")
497
536
 
498
- init = commands.add_parser("init", help="create a standard Lake project in shared mode")
499
- init.add_argument("path", type=Path)
500
- init.add_argument(
537
+ init = commands.add_parser(
538
+ "init", help="create a latest-Mathlib project or adopt an existing Lake project"
539
+ )
540
+ init.add_argument("path", type=Path, nargs="?", default=Path("."))
541
+ init_context = init.add_mutually_exclusive_group()
542
+ init_context.add_argument(
501
543
  "--mathlib",
502
544
  nargs="?",
503
545
  const="latest",
546
+ default="latest",
504
547
  help="use the newest cataloged Mathlib, or select a version such as 4.33.0",
505
548
  )
549
+ init_context.add_argument(
550
+ "--core",
551
+ dest="mathlib",
552
+ action="store_const",
553
+ const=None,
554
+ help="create a core-only project",
555
+ )
506
556
  init.add_argument("--toolchain")
557
+ init.add_argument("--seed-from", type=Path, help="reuse an exact local project or project tree")
558
+ init.add_argument("--plan", action="store_true", help="show cost and reuse without changes")
559
+ init.add_argument("--offline", action="store_true", help="require exact local dependencies")
560
+ init.add_argument("--max-download", metavar="SIZE", help="fail above SIZE, e.g. 500MiB")
507
561
  init.add_argument(
508
562
  "--no-agents",
509
563
  dest="agents",
@@ -512,6 +566,22 @@ def parser() -> argparse.ArgumentParser:
512
566
  )
513
567
  init.add_argument("--json", action="store_true")
514
568
 
569
+ scan = commands.add_parser(
570
+ "scan", help="register local Lake projects as reusable exact dependency seeds"
571
+ )
572
+ scan.add_argument("path", type=Path, nargs="?", default=Path("."))
573
+ scan.add_argument("--no-recursive", dest="recursive", action="store_false")
574
+ scan.add_argument("--json", action="store_true")
575
+
576
+ update = commands.add_parser("update", help="move this project to the latest stable Mathlib")
577
+ update.add_argument("path", type=Path, nargs="?", default=Path("."))
578
+ update.add_argument("--seed-from", type=Path, help="reuse an exact local project or tree")
579
+ update.add_argument("--plan", action="store_true", help="show the update without changes")
580
+ update.add_argument("--yes", action="store_true", help="apply without an interactive prompt")
581
+ update.add_argument("--offline", action="store_true", help="require exact local dependencies")
582
+ update.add_argument("--max-download", metavar="SIZE", help="fail above SIZE, e.g. 500MiB")
583
+ update.add_argument("--json", action="store_true")
584
+
515
585
  attach = commands.add_parser(
516
586
  "attach", help="plan or adopt shared dependencies for existing Lake projects"
517
587
  )
@@ -574,31 +644,89 @@ def main(argv: list[str] | None = None) -> int:
574
644
  args = parser().parse_args(argv)
575
645
  operation_started = time.monotonic()
576
646
  try:
647
+ selected_availability = (
648
+ "local" if args.command in {"init", "update"} and args.offline else args.availability
649
+ )
650
+ selected_download_limit = (
651
+ parse_byte_size(args.max_download)
652
+ if args.command in {"init", "update"} and args.max_download is not None
653
+ else None
654
+ )
577
655
  runtime = Runtime(
578
656
  home=args.home,
579
657
  on_event=None if args.quiet else _progress,
580
- availability=args.availability,
658
+ availability=selected_availability,
581
659
  libraries=args.libraries,
660
+ max_download_bytes=selected_download_limit,
582
661
  publisher_verification=args.publisher_verification,
583
662
  trusted_publisher=args.trusted_publisher,
584
663
  trusted_issuer=args.trusted_issuer,
585
664
  verification_tool=args.verification_tool,
586
665
  )
587
666
  if args.command == "init":
667
+ init_plan = runtime.plan_project_init(
668
+ args.path,
669
+ mathlib=args.mathlib,
670
+ toolchain=args.toolchain,
671
+ seed_from=args.seed_from,
672
+ )
673
+ if args.plan:
674
+ if args.json:
675
+ _json(init_plan.to_dict())
676
+ else:
677
+ _render_init_plan(init_plan)
678
+ return 0
679
+ if not args.json:
680
+ _render_init_plan(init_plan)
588
681
  init_result = runtime.init_project(
589
682
  args.path,
590
683
  mathlib=args.mathlib,
591
684
  toolchain=args.toolchain,
592
685
  agents=args.agents,
686
+ seed_from=args.seed_from,
593
687
  )
594
688
  if args.json:
595
689
  _json(init_result.to_dict())
596
690
  else:
597
- print(f"Created and attached {init_result.root}")
691
+ verb = "Ready" if init_plan.action == "create" else "Attached"
692
+ print(f"{verb}: {init_result.root}")
598
693
  print(f"Shared packages: {init_result.packages}")
599
694
  if args.agents:
600
695
  print(f"Agent guide: {init_result.root / 'AGENTS.md'}")
601
- print(f"Next: cd {init_result.root} && lean-runtime build .")
696
+ print(f"Next: cd {init_result.root} && lean-runtime build")
697
+ return 0
698
+ if args.command == "scan":
699
+ scan_result = runtime.scan_projects(args.path, recursive=args.recursive)
700
+ if args.json:
701
+ _json(scan_result.to_dict())
702
+ else:
703
+ print(f"Registered {len(scan_result.projects)} Lake project(s)")
704
+ for project_root in scan_result.projects:
705
+ print(f" {project_root}")
706
+ return 0
707
+ if args.command == "update":
708
+ update_plan = runtime.plan_project_update(args.path, seed_from=args.seed_from)
709
+ if not args.json:
710
+ _render_update_plan(update_plan)
711
+ if args.plan or not update_plan.changed or not update_plan.ready:
712
+ if args.json:
713
+ _json({**update_plan.to_dict(), "applied": False})
714
+ return 0 if update_plan.ready else 1
715
+ apply_update = args.yes
716
+ if not apply_update and sys.stdin.isatty() and not args.json:
717
+ answer = input("Apply this update? [Y/n] ").strip().lower()
718
+ apply_update = answer in {"", "y", "yes"}
719
+ if not apply_update:
720
+ if args.json:
721
+ _json({**update_plan.to_dict(), "applied": False})
722
+ else:
723
+ print("No changes made. Re-run with --yes to apply noninteractively.")
724
+ return 0
725
+ runtime.update_project(args.path, seed_from=args.seed_from)
726
+ if args.json:
727
+ _json({**update_plan.to_dict(), "applied": True})
728
+ else:
729
+ print(f"Updated and attached: {update_plan.root}")
602
730
  return 0
603
731
  if args.command == "attach":
604
732
  adoption_plan = runtime.plan_project_adoption(args.path, recursive=args.recursive)
@@ -1042,19 +1170,44 @@ def main(argv: list[str] | None = None) -> int:
1042
1170
  _render_cleanup(gc_report, gc_downloads)
1043
1171
  return 0
1044
1172
  if args.command == "check":
1173
+ if args.project is not None and args.package_refs:
1174
+ raise ValueError("check cannot combine --project with --with")
1045
1175
  if args.package_refs:
1046
1176
  if len(args.inputs) != 1:
1047
1177
  raise ValueError("check with --with expects exactly one FILE")
1048
1178
  environment = runtime.open_references(args.package_refs, toolchain=args.toolchain)
1049
1179
  source_file = Path(args.inputs[0])
1180
+ elif len(args.inputs) == 1:
1181
+ if args.include:
1182
+ raise ValueError("local project checks do not accept --include")
1183
+ source_file = Path(args.inputs[0])
1184
+ if str(source_file) == "-":
1185
+ result = runtime.check(
1186
+ sys.stdin.read(),
1187
+ toolchain=args.toolchain,
1188
+ project=args.project,
1189
+ policy=_policy(args),
1190
+ )
1191
+ else:
1192
+ result = runtime.check_file(
1193
+ source_file,
1194
+ toolchain=args.toolchain,
1195
+ project=args.project,
1196
+ policy=_policy(args),
1197
+ )
1198
+ source_file = None
1050
1199
  else:
1051
1200
  if len(args.inputs) != 2:
1052
- raise ValueError("check expects ENVIRONMENT FILE, or FILE with --with")
1201
+ raise ValueError("check expects FILE, ENVIRONMENT FILE, or FILE with --with")
1053
1202
  if args.toolchain:
1054
1203
  raise ValueError("check --toolchain is only valid with --with")
1204
+ if args.project:
1205
+ raise ValueError("check --project is only valid with a single FILE")
1055
1206
  environment = runtime.environment(args.inputs[0])
1056
1207
  source_file = Path(args.inputs[1])
1057
- if str(source_file) == "-":
1208
+ if source_file is None:
1209
+ pass
1210
+ elif str(source_file) == "-":
1058
1211
  if args.include:
1059
1212
  raise ValueError("stdin entrypoints cannot be combined with --include")
1060
1213
  result = environment.check(sys.stdin.read(), policy=_policy(args))
@@ -106,6 +106,7 @@ class ProjectProvenance:
106
106
  manifest_digest: str | None
107
107
  git_revision: str | None
108
108
  git_dirty: bool | None
109
+ workspace_id: str | None = None
109
110
 
110
111
  def to_dict(self) -> dict[str, Any]:
111
112
  return asdict(self)