gitgrip 1.5.0__tar.gz → 2.0.0a1__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 (221) hide show
  1. {gitgrip-1.5.0/gitgrip.egg-info → gitgrip-2.0.0a1}/PKG-INFO +1 -1
  2. {gitgrip-1.5.0 → gitgrip-2.0.0a1/gitgrip.egg-info}/PKG-INFO +1 -1
  3. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/gitgrip.egg-info/SOURCES.txt +19 -7
  4. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/gitgrip.egg-info/entry_points.txt +1 -0
  5. gitgrip-2.0.0a1/gr2/overlay/__init__.py +9 -0
  6. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/prototypes/concurrent_lease_stress.py +4 -3
  7. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/prototypes/concurrent_workspace_cap_stress.py +4 -3
  8. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/prototypes/cross_mode_lane_stress.py +21 -21
  9. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/prototypes/lane_workspace_prototype.py +11 -11
  10. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/prototypes/python_exec_playground.py +2 -1
  11. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/prototypes/python_hook_runtime_playground.py +2 -1
  12. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/prototypes/python_migration_playground.py +2 -1
  13. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/prototypes/python_review_checkout_playground.py +2 -1
  14. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/prototypes/python_spec_apply_playground.py +2 -1
  15. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/prototypes/real_git_lane_materialization.py +3 -2
  16. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/prototypes/real_git_playground.py +1 -1
  17. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/pyproject.toml +7 -13
  18. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/python_cli/app.py +224 -36
  19. gitgrip-2.0.0a1/python_cli/git_review.py +808 -0
  20. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/python_cli/gitops.py +158 -4
  21. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/python_cli/hooks.py +29 -0
  22. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/python_cli/launch_exec.py +87 -11
  23. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/python_cli/migration.py +1 -2
  24. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/python_cli/project_review.py +3 -3
  25. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/python_cli/review.py +1 -1
  26. gitgrip-2.0.0a1/python_cli/review_dispatch.py +52 -0
  27. gitgrip-2.0.0a1/python_cli/review_rebind.py +315 -0
  28. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/python_cli/review_run.py +269 -14
  29. gitgrip-2.0.0a1/python_cli/review_runners.py +133 -0
  30. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/python_cli/syncops.py +61 -4
  31. gitgrip-2.0.0a1/tests/test_conftest_git_isolation.py +219 -0
  32. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_ensure_lane_checkout_reference_clone.py +1 -1
  33. gitgrip-2.0.0a1/tests/test_foreground_launch_runtime.py +155 -0
  34. gitgrip-2.0.0a1/tests/test_git_review.py +780 -0
  35. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_lane_create_fork_base_cli.py +2 -2
  36. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_lane_lifecycle_safety.py +5 -5
  37. gitgrip-2.0.0a1/tests/test_projection_tracked_dest.py +183 -0
  38. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_review_bind_fork_base.py +1 -1
  39. gitgrip-2.0.0a1/tests/test_review_dispatch.py +105 -0
  40. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_review_open_lane.py +7 -2
  41. gitgrip-2.0.0a1/tests/test_review_rebind.py +198 -0
  42. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_review_run.py +151 -15
  43. gitgrip-2.0.0a1/tests/test_review_run_import_isolation.py +160 -0
  44. gitgrip-2.0.0a1/tests/test_review_run_rerun_and_refusal_receipt.py +116 -0
  45. gitgrip-2.0.0a1/tests/test_review_runners.py +217 -0
  46. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_sprint21_sync_platform.py +27 -0
  47. gitgrip-2.0.0a1/tests/test_store_verb_rename.py +46 -0
  48. gitgrip-2.0.0a1/tests/test_sync_fast_forward.py +238 -0
  49. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_sync_fetch.py +10 -5
  50. gitgrip-2.0.0a1/tests/test_sync_seed_local.py +241 -0
  51. gitgrip-2.0.0a1/tests/test_sync_ssh_rewrite.py +326 -0
  52. gitgrip-2.0.0a1/tests/test_sync_status_probe.py +232 -0
  53. gitgrip-2.0.0a1/tests/test_version_static.py +111 -0
  54. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_workspace_convert_clone.py +1 -1
  55. gitgrip-1.5.0/MANIFEST.in +0 -6
  56. gitgrip-1.5.0/VERSION +0 -1
  57. gitgrip-1.5.0/_build/__pycache__/backend.cpython-311.pyc +0 -0
  58. gitgrip-1.5.0/_build/__pycache__/version_from_cargo.cpython-311.pyc +0 -0
  59. gitgrip-1.5.0/_build/backend.py +0 -58
  60. gitgrip-1.5.0/_build/version_from_cargo.py +0 -43
  61. gitgrip-1.5.0/gr2/overlay/__init__.py +0 -6
  62. gitgrip-1.5.0/tests/test_version_single_sourced.py +0 -96
  63. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/README.md +0 -0
  64. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/gitgrip.egg-info/dependency_links.txt +0 -0
  65. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/gitgrip.egg-info/requires.txt +0 -0
  66. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/gitgrip.egg-info/top_level.txt +0 -0
  67. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/gr2/__init__.py +0 -0
  68. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/gr2/overlay/activate.py +0 -0
  69. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/gr2/overlay/agent_manifest.py +0 -0
  70. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/gr2/overlay/cli.py +0 -0
  71. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/gr2/overlay/cross_repo.py +0 -0
  72. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/gr2/overlay/drivers.py +0 -0
  73. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/gr2/overlay/introspection.py +0 -0
  74. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/gr2/overlay/language_drivers.py +0 -0
  75. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/gr2/overlay/objects.py +0 -0
  76. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/gr2/overlay/perf.py +0 -0
  77. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/gr2/overlay/refs.py +0 -0
  78. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/gr2/overlay/trust.py +0 -0
  79. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/gr2/overlay/types.py +0 -0
  80. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/gr2/overlay/units.py +0 -0
  81. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/gr2/overlay/workspace_spec.py +0 -0
  82. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/gr2/schemas/gr2-materialization-plan-v1.schema.json +0 -0
  83. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/gr2_overlay/__init__.py +0 -0
  84. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/prototypes/__init__.py +0 -0
  85. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/prototypes/cache_materialization_probe.py +0 -0
  86. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/prototypes/concurrent_event_stress.py +0 -0
  87. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/prototypes/contribution_protocol.py +0 -0
  88. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/prototypes/jsonl_store.py +0 -0
  89. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/prototypes/layout_model_probe.py +0 -0
  90. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/prototypes/propagation_daemon.py +0 -0
  91. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/prototypes/propagation_state_machine.py +0 -0
  92. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/prototypes/recall_lane_history.py +0 -0
  93. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/prototypes/repo_maintenance_prototype.py +0 -0
  94. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/prototypes/repo_transport_probe.py +0 -0
  95. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/python_cli/__init__.py +0 -0
  96. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/python_cli/__main__.py +0 -0
  97. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/python_cli/add.py +0 -0
  98. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/python_cli/branch.py +0 -0
  99. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/python_cli/channel_bridge.py +0 -0
  100. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/python_cli/clone_exec.py +0 -0
  101. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/python_cli/commit.py +0 -0
  102. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/python_cli/config.py +0 -0
  103. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/python_cli/env_exec.py +0 -0
  104. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/python_cli/events.py +0 -0
  105. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/python_cli/execops.py +0 -0
  106. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/python_cli/failures.py +0 -0
  107. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/python_cli/file_exec.py +0 -0
  108. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/python_cli/grip.py +0 -0
  109. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/python_cli/grip_cli.py +0 -0
  110. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/python_cli/merge_verification.py +0 -0
  111. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/python_cli/open_gr_review.py +0 -0
  112. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/python_cli/platform.py +0 -0
  113. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/python_cli/pr.py +0 -0
  114. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/python_cli/prune.py +0 -0
  115. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/python_cli/push.py +0 -0
  116. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/python_cli/review_ephemeral.py +0 -0
  117. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/python_cli/spec_apply.py +0 -0
  118. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/python_cli/staging_cleanup.py +0 -0
  119. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/python_cli/target.py +0 -0
  120. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/python_cli/workspace_snapshot.py +0 -0
  121. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/setup.cfg +0 -0
  122. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_add.py +0 -0
  123. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_agent_manifest_overlay_source.py +0 -0
  124. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_app_event_outcomes.py +0 -0
  125. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_apply_convergence.py +0 -0
  126. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_branch.py +0 -0
  127. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_channel_bridge.py +0 -0
  128. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_clone_materialization.py +0 -0
  129. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_commit.py +0 -0
  130. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_config_base_path_guard.py +0 -0
  131. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_config_overlay.py +0 -0
  132. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_contribution_protocol.py +0 -0
  133. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_env_materialization.py +0 -0
  134. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_event_log_integrity.py +0 -0
  135. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_event_outcome_policy.py +0 -0
  136. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_events.py +0 -0
  137. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_events_torn_line.py +0 -0
  138. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_execops.py +0 -0
  139. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_failure_event_outcome.py +0 -0
  140. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_gr2_packaging.py +0 -0
  141. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_gr2_review_receipt.py +0 -0
  142. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_grip_cli.py +0 -0
  143. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_grip_hardening.py +0 -0
  144. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_grip_object_model.py +0 -0
  145. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_grip_snapshot.py +0 -0
  146. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_hook_events.py +0 -0
  147. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_hook_hardening.py +0 -0
  148. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_jsonl_store.py +0 -0
  149. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_lane_lease_show_json.py +0 -0
  150. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_lane_toml_serialization.py +0 -0
  151. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_launch_primitive.py +0 -0
  152. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_m2_overlay_hindsight.py +0 -0
  153. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_m2_overlay_mem0.py +0 -0
  154. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_m2_overlay_zep.py +0 -0
  155. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_materialization_plan_contract.py +0 -0
  156. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_merge_evidence.py +0 -0
  157. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_merge_parent_verification.py +0 -0
  158. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_migration.py +0 -0
  159. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_migration_overlay_compatibility.py +0 -0
  160. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_no_bare_python_cli_imports.py +0 -0
  161. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_null_current_lane_refusal.py +0 -0
  162. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_open_gr_enter.py +0 -0
  163. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_open_project_refusal_reason_cli.py +0 -0
  164. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_overlay_acceptance.py +0 -0
  165. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_overlay_activate.py +0 -0
  166. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_overlay_cli.py +0 -0
  167. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_overlay_cli_wiring.py +0 -0
  168. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_overlay_composition_merge.py +0 -0
  169. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_overlay_cross_repo_atomic_apply.py +0 -0
  170. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_overlay_cross_repo_perf_gate.py +0 -0
  171. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_overlay_cross_repo_rollback.py +0 -0
  172. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_overlay_driver_registry.py +0 -0
  173. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_overlay_introspection.py +0 -0
  174. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_overlay_multi_stack.py +0 -0
  175. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_overlay_object_encoding.py +0 -0
  176. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_overlay_perf_gates.py +0 -0
  177. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_overlay_python_driver.py +0 -0
  178. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_overlay_tier_b_encoding.py +0 -0
  179. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_overlay_tier_b_perf_gates.py +0 -0
  180. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_overlay_tier_b_repo_state.py +0 -0
  181. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_overlay_tier_b_staging_discipline.py +0 -0
  182. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_overlay_trust_model.py +0 -0
  183. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_overlay_workspace_spec.py +0 -0
  184. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_pr_events.py +0 -0
  185. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_pr_merge_method.py +0 -0
  186. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_pr_merge_partial_failure.py +0 -0
  187. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_project_file_materialization.py +0 -0
  188. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_project_review_range_reconstruction.py +0 -0
  189. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_project_review_three_repo.py +0 -0
  190. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_propagation_contribution.py +0 -0
  191. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_propagation_daemon.py +0 -0
  192. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_propagation_state_machine.py +0 -0
  193. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_prune.py +0 -0
  194. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_push.py +0 -0
  195. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_repo_status_linked_worktree.py +0 -0
  196. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_repo_status_schema_version.py +0 -0
  197. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_repo_status_symlinked_git_dir.py +0 -0
  198. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_review_bind_from_range.py +0 -0
  199. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_review_bind_verify.py +0 -0
  200. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_review_cli.py +0 -0
  201. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_review_close_gr.py +0 -0
  202. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_review_create_project_cli.py +0 -0
  203. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_review_ephemeral.py +0 -0
  204. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_review_verify_inside.py +0 -0
  205. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_rmtree_or_refuse.py +0 -0
  206. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_snapshot_id_prefix_resolution.py +0 -0
  207. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_spec_apply_event_outcomes.py +0 -0
  208. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_staging_cleanup.py +0 -0
  209. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_sync_event_outcomes.py +0 -0
  210. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_target.py +0 -0
  211. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_tmux_launch_runtime.py +0 -0
  212. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_unit_abort.py +0 -0
  213. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_unit_apply.py +0 -0
  214. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_unit_apply_dry_run.py +0 -0
  215. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_unit_manifest_schema.py +0 -0
  216. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_unit_propose.py +0 -0
  217. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_unit_topological_apply.py +0 -0
  218. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_workspace_edit_lease_cap.py +0 -0
  219. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_workspace_identity_boundary.py +0 -0
  220. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_workspace_init_from_topology.py +0 -0
  221. {gitgrip-1.5.0 → gitgrip-2.0.0a1}/tests/test_workspace_snapshot.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gitgrip
3
- Version: 1.5.0
3
+ Version: 2.0.0a1
4
4
  Summary: gr2 overlay substrate: config-overlay capture, composition, and materialization
5
5
  Requires-Python: >=3.11
6
6
  Requires-Dist: typer>=0.9
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gitgrip
3
- Version: 1.5.0
3
+ Version: 2.0.0a1
4
4
  Summary: gr2 overlay substrate: config-overlay capture, composition, and materialization
5
5
  Requires-Python: >=3.11
6
6
  Requires-Dist: typer>=0.9
@@ -1,11 +1,5 @@
1
- MANIFEST.in
2
1
  README.md
3
- VERSION
4
2
  pyproject.toml
5
- _build/backend.py
6
- _build/version_from_cargo.py
7
- _build/__pycache__/backend.cpython-311.pyc
8
- _build/__pycache__/version_from_cargo.cpython-311.pyc
9
3
  gitgrip.egg-info/PKG-INFO
10
4
  gitgrip.egg-info/SOURCES.txt
11
5
  gitgrip.egg-info/dependency_links.txt
@@ -66,6 +60,7 @@ python_cli/events.py
66
60
  python_cli/execops.py
67
61
  python_cli/failures.py
68
62
  python_cli/file_exec.py
63
+ python_cli/git_review.py
69
64
  python_cli/gitops.py
70
65
  python_cli/grip.py
71
66
  python_cli/grip_cli.py
@@ -80,8 +75,11 @@ python_cli/project_review.py
80
75
  python_cli/prune.py
81
76
  python_cli/push.py
82
77
  python_cli/review.py
78
+ python_cli/review_dispatch.py
83
79
  python_cli/review_ephemeral.py
80
+ python_cli/review_rebind.py
84
81
  python_cli/review_run.py
82
+ python_cli/review_runners.py
85
83
  python_cli/spec_apply.py
86
84
  python_cli/staging_cleanup.py
87
85
  python_cli/syncops.py
@@ -97,6 +95,7 @@ tests/test_clone_materialization.py
97
95
  tests/test_commit.py
98
96
  tests/test_config_base_path_guard.py
99
97
  tests/test_config_overlay.py
98
+ tests/test_conftest_git_isolation.py
100
99
  tests/test_contribution_protocol.py
101
100
  tests/test_ensure_lane_checkout_reference_clone.py
102
101
  tests/test_env_materialization.py
@@ -106,6 +105,8 @@ tests/test_events.py
106
105
  tests/test_events_torn_line.py
107
106
  tests/test_execops.py
108
107
  tests/test_failure_event_outcome.py
108
+ tests/test_foreground_launch_runtime.py
109
+ tests/test_git_review.py
109
110
  tests/test_gr2_packaging.py
110
111
  tests/test_gr2_review_receipt.py
111
112
  tests/test_grip_cli.py
@@ -158,6 +159,7 @@ tests/test_pr_merge_partial_failure.py
158
159
  tests/test_project_file_materialization.py
159
160
  tests/test_project_review_range_reconstruction.py
160
161
  tests/test_project_review_three_repo.py
162
+ tests/test_projection_tracked_dest.py
161
163
  tests/test_propagation_contribution.py
162
164
  tests/test_propagation_daemon.py
163
165
  tests/test_propagation_state_machine.py
@@ -172,17 +174,27 @@ tests/test_review_bind_verify.py
172
174
  tests/test_review_cli.py
173
175
  tests/test_review_close_gr.py
174
176
  tests/test_review_create_project_cli.py
177
+ tests/test_review_dispatch.py
175
178
  tests/test_review_ephemeral.py
176
179
  tests/test_review_open_lane.py
180
+ tests/test_review_rebind.py
177
181
  tests/test_review_run.py
182
+ tests/test_review_run_import_isolation.py
183
+ tests/test_review_run_rerun_and_refusal_receipt.py
184
+ tests/test_review_runners.py
178
185
  tests/test_review_verify_inside.py
179
186
  tests/test_rmtree_or_refuse.py
180
187
  tests/test_snapshot_id_prefix_resolution.py
181
188
  tests/test_spec_apply_event_outcomes.py
182
189
  tests/test_sprint21_sync_platform.py
183
190
  tests/test_staging_cleanup.py
191
+ tests/test_store_verb_rename.py
184
192
  tests/test_sync_event_outcomes.py
193
+ tests/test_sync_fast_forward.py
185
194
  tests/test_sync_fetch.py
195
+ tests/test_sync_seed_local.py
196
+ tests/test_sync_ssh_rewrite.py
197
+ tests/test_sync_status_probe.py
186
198
  tests/test_target.py
187
199
  tests/test_tmux_launch_runtime.py
188
200
  tests/test_unit_abort.py
@@ -191,7 +203,7 @@ tests/test_unit_apply_dry_run.py
191
203
  tests/test_unit_manifest_schema.py
192
204
  tests/test_unit_propose.py
193
205
  tests/test_unit_topological_apply.py
194
- tests/test_version_single_sourced.py
206
+ tests/test_version_static.py
195
207
  tests/test_workspace_convert_clone.py
196
208
  tests/test_workspace_edit_lease_cap.py
197
209
  tests/test_workspace_identity_boundary.py
@@ -1,2 +1,3 @@
1
1
  [console_scripts]
2
+ git-review = gr2.python_cli.git_review:main
2
3
  gr2 = gr2.python_cli.app:main
@@ -0,0 +1,9 @@
1
+ """gr2 overlay substrate: config-overlay capture, composition, and materialization.
2
+
3
+ M1 scope: Tier A only (config files), eager materialization, trust-gated.
4
+
5
+ The distribution version is single-sourced from the package metadata (the static
6
+ number in gr2/pyproject.toml); this module carries no ``__version__`` literal so a
7
+ stale third number cannot drift here. Read it with
8
+ ``importlib.metadata.version("gitgrip")`` or ``gr2 --version``.
9
+ """
@@ -8,6 +8,7 @@ import json
8
8
  import multiprocessing
9
9
  import os
10
10
  import subprocess
11
+ import sys
11
12
  import tempfile
12
13
  from pathlib import Path
13
14
 
@@ -65,7 +66,7 @@ repos = ["app"]
65
66
  def create_lane(root: Path, workspace_root: Path) -> None:
66
67
  run(
67
68
  [
68
- "python3",
69
+ sys.executable,
69
70
  str(lane_proto(root)),
70
71
  "create-lane",
71
72
  str(workspace_root),
@@ -88,7 +89,7 @@ def worker(workspace_root: str, actor: str, queue, disable_locking: bool) -> Non
88
89
  env["GR2_LEASE_TEST_DELAY"] = "0.02"
89
90
  proc = run(
90
91
  [
91
- "python3",
92
+ sys.executable,
92
93
  str(lane_proto(root)),
93
94
  "acquire-lane-lease",
94
95
  workspace_root,
@@ -154,7 +155,7 @@ def release_all(root: Path, workspace_root: Path, disable_locking: bool) -> None
154
155
  for actor in ("worker:a", "worker:b"):
155
156
  run(
156
157
  [
157
- "python3",
158
+ sys.executable,
158
159
  str(lane_proto(root)),
159
160
  "release-lane-lease",
160
161
  str(workspace_root),
@@ -8,6 +8,7 @@ import json
8
8
  import multiprocessing
9
9
  import os
10
10
  import subprocess
11
+ import sys
11
12
  import tempfile
12
13
  from pathlib import Path
13
14
 
@@ -65,7 +66,7 @@ repos = ["app"]
65
66
  for unit, lane in (("atlas", "lane-a"), ("apollo", "lane-b")):
66
67
  result = _run(
67
68
  [
68
- "python3",
69
+ sys.executable,
69
70
  str(lane_proto(root)),
70
71
  "create-lane",
71
72
  str(workspace_root),
@@ -100,7 +101,7 @@ def _acquire_worker(
100
101
  env["GR2_LEASE_TEST_DELAY"] = "0.04"
101
102
  result = _run(
102
103
  [
103
- "python3",
104
+ sys.executable,
104
105
  str(lane_proto(repo_root())),
105
106
  "acquire-lane-lease",
106
107
  workspace_root,
@@ -190,7 +191,7 @@ def sequential_control() -> dict[str, object]:
190
191
  outcomes.append(
191
192
  _run(
192
193
  [
193
- "python3",
194
+ sys.executable,
194
195
  str(lane_proto(repo_root())),
195
196
  "acquire-lane-lease",
196
197
  str(workspace_root),
@@ -155,7 +155,7 @@ repos = ["app", "api", "web", "billing"]
155
155
  def create_lane(root: Path, workspace_root: Path, owner_unit: str, lane_name: str, repos: str, branch: str, lane_type: str = "feature") -> None:
156
156
  run(
157
157
  [
158
- "python3",
158
+ sys.executable,
159
159
  str(lane_proto(root)),
160
160
  "create-lane",
161
161
  str(workspace_root),
@@ -174,7 +174,7 @@ def create_lane(root: Path, workspace_root: Path, owner_unit: str, lane_name: st
174
174
  def create_review_lane(root: Path, workspace_root: Path, owner_unit: str, repo: str, pr_number: int) -> None:
175
175
  run(
176
176
  [
177
- "python3",
177
+ sys.executable,
178
178
  str(lane_proto(root)),
179
179
  "create-review-lane",
180
180
  str(workspace_root),
@@ -188,7 +188,7 @@ def create_review_lane(root: Path, workspace_root: Path, owner_unit: str, repo:
188
188
  def plan_exec_json(root: Path, workspace_root: Path, owner_unit: str, lane_name: str, command_text: str) -> list[dict]:
189
189
  proc = run(
190
190
  [
191
- "python3",
191
+ sys.executable,
192
192
  str(lane_proto(root)),
193
193
  "plan-exec",
194
194
  str(workspace_root),
@@ -204,7 +204,7 @@ def plan_exec_json(root: Path, workspace_root: Path, owner_unit: str, lane_name:
204
204
 
205
205
  def acquire_lease(root: Path, workspace_root: Path, owner_unit: str, lane_name: str, actor: str, mode: str, ttl_seconds: int = 900, force: bool = False, expect_ok: bool = True) -> subprocess.CompletedProcess[str]:
206
206
  argv = [
207
- "python3",
207
+ sys.executable,
208
208
  str(lane_proto(root)),
209
209
  "acquire-lane-lease",
210
210
  str(workspace_root),
@@ -228,7 +228,7 @@ def acquire_lease(root: Path, workspace_root: Path, owner_unit: str, lane_name:
228
228
  def show_leases_json(root: Path, workspace_root: Path, owner_unit: str, lane_name: str) -> list[dict]:
229
229
  proc = run(
230
230
  [
231
- "python3",
231
+ sys.executable,
232
232
  str(lane_proto(root)),
233
233
  "show-lane-leases",
234
234
  str(workspace_root),
@@ -244,7 +244,7 @@ def show_leases_json(root: Path, workspace_root: Path, owner_unit: str, lane_nam
244
244
  def check_review_requirements_json(root: Path, workspace_root: Path, repo: str, pr_number: int) -> dict:
245
245
  proc = run(
246
246
  [
247
- "python3",
247
+ sys.executable,
248
248
  str(lane_proto(root)),
249
249
  "check-review-requirements",
250
250
  str(workspace_root),
@@ -259,7 +259,7 @@ def check_review_requirements_json(root: Path, workspace_root: Path, repo: str,
259
259
 
260
260
  def list_lanes_text(root: Path, workspace_root: Path, owner_unit: str | None = None) -> str:
261
261
  argv = [
262
- "python3",
262
+ sys.executable,
263
263
  str(lane_proto(root)),
264
264
  "list-lanes",
265
265
  str(workspace_root),
@@ -280,7 +280,7 @@ def plan_handoff_json(
280
280
  target_lane_name: str | None = None,
281
281
  ) -> dict:
282
282
  argv = [
283
- "python3",
283
+ sys.executable,
284
284
  str(lane_proto(root)),
285
285
  "plan-handoff",
286
286
  str(workspace_root),
@@ -339,7 +339,7 @@ def scenario_agent_handoff_relay(root: Path, workspace_root: Path) -> ScenarioRe
339
339
  create_lane(root, workspace_root, "atlas", "feat-router", "app,api", "feat/router")
340
340
  run(
341
341
  [
342
- "python3",
342
+ sys.executable,
343
343
  str(lane_proto(root)),
344
344
  "share-lane",
345
345
  str(workspace_root),
@@ -358,7 +358,7 @@ def scenario_agent_handoff_relay(root: Path, workspace_root: Path) -> ScenarioRe
358
358
  )
359
359
  run(
360
360
  [
361
- "python3",
361
+ sys.executable,
362
362
  str(lane_proto(root)),
363
363
  "create-continuation-lane",
364
364
  str(workspace_root),
@@ -457,7 +457,7 @@ def scenario_single_agent_interrupt_recovery(root: Path, workspace_root: Path) -
457
457
  create_review_lane(root, workspace_root, "atlas", "app", 123)
458
458
  run(
459
459
  [
460
- "python3",
460
+ sys.executable,
461
461
  str(lane_proto(root)),
462
462
  "enter-lane",
463
463
  str(workspace_root),
@@ -469,7 +469,7 @@ def scenario_single_agent_interrupt_recovery(root: Path, workspace_root: Path) -
469
469
  )
470
470
  run(
471
471
  [
472
- "python3",
472
+ sys.executable,
473
473
  str(lane_proto(root)),
474
474
  "enter-lane",
475
475
  str(workspace_root),
@@ -482,7 +482,7 @@ def scenario_single_agent_interrupt_recovery(root: Path, workspace_root: Path) -
482
482
  lane_listing = list_lanes_text(root, workspace_root, "atlas")
483
483
  current_lane_proc = run(
484
484
  [
485
- "python3",
485
+ sys.executable,
486
486
  str(lane_proto(root)),
487
487
  "current-lane",
488
488
  str(workspace_root),
@@ -591,7 +591,7 @@ def scenario_synapt_lane_events(root: Path, workspace_root: Path) -> ScenarioRes
591
591
  create_lane(root, workspace_root, "atlas", "feat-events", "app,api", "feat/events")
592
592
  run(
593
593
  [
594
- "python3",
594
+ sys.executable,
595
595
  str(lane_proto(root)),
596
596
  "enter-lane",
597
597
  str(workspace_root),
@@ -606,7 +606,7 @@ def scenario_synapt_lane_events(root: Path, workspace_root: Path) -> ScenarioRes
606
606
  acquire_lease(root, workspace_root, "atlas", "feat-events", "agent:atlas", "exec")
607
607
  run(
608
608
  [
609
- "python3",
609
+ sys.executable,
610
610
  str(lane_proto(root)),
611
611
  "release-lane-lease",
612
612
  str(workspace_root),
@@ -618,7 +618,7 @@ def scenario_synapt_lane_events(root: Path, workspace_root: Path) -> ScenarioRes
618
618
  )
619
619
  run(
620
620
  [
621
- "python3",
621
+ sys.executable,
622
622
  str(lane_proto(root)),
623
623
  "exit-lane",
624
624
  str(workspace_root),
@@ -631,7 +631,7 @@ def scenario_synapt_lane_events(root: Path, workspace_root: Path) -> ScenarioRes
631
631
  )
632
632
  history_proc = run(
633
633
  [
634
- "python3",
634
+ sys.executable,
635
635
  str(lane_proto(root)),
636
636
  "lane-history",
637
637
  str(workspace_root),
@@ -734,7 +734,7 @@ def scenario_solo_human_forgets_lane(root: Path, workspace_root: Path) -> Scenar
734
734
  create_lane(root, workspace_root, "layne", "feat-release", "app,web", "feat/release")
735
735
  run(
736
736
  [
737
- "python3",
737
+ sys.executable,
738
738
  str(lane_proto(root)),
739
739
  "enter-lane",
740
740
  str(workspace_root),
@@ -747,7 +747,7 @@ def scenario_solo_human_forgets_lane(root: Path, workspace_root: Path) -> Scenar
747
747
  create_review_lane(root, workspace_root, "layne", "app", 456)
748
748
  run(
749
749
  [
750
- "python3",
750
+ sys.executable,
751
751
  str(lane_proto(root)),
752
752
  "enter-lane",
753
753
  str(workspace_root),
@@ -761,7 +761,7 @@ def scenario_solo_human_forgets_lane(root: Path, workspace_root: Path) -> Scenar
761
761
  lane_listing = list_lanes_text(root, workspace_root, "layne")
762
762
  current_lane_proc = run(
763
763
  [
764
- "python3",
764
+ sys.executable,
765
765
  str(lane_proto(root)),
766
766
  "current-lane",
767
767
  str(workspace_root),
@@ -850,7 +850,7 @@ def scenario_global_edit_lease_cap(root: Path, workspace_root: Path) -> Scenario
850
850
  ]:
851
851
  run(
852
852
  [
853
- "python3",
853
+ sys.executable,
854
854
  str(lane_proto(root)),
855
855
  "release-lane-lease",
856
856
  str(workspace_root),
@@ -88,7 +88,7 @@ class LaneMetadata:
88
88
  creation_source: str
89
89
  shared_with: list[str]
90
90
  handoff_source: dict[str, str] | None
91
- # gr2-lane-author-shape ruling (2026-09-03): lane_kind is required on every
91
+ # By design, lane_kind is required on every
92
92
  # lane document so a reader never infers the reconstruction guarantee. A
93
93
  # "materialized" lane holds an isolated clone pinned at a head; a "bound"
94
94
  # lane is a label on the author's own existing worktree (single-repo only),
@@ -99,7 +99,7 @@ class LaneMetadata:
99
99
  lane_kind: str = "materialized"
100
100
  bound_worktree: str | None = None
101
101
  bound_head: str | None = None
102
- # fork-base ruling (2026-09-04): the per-repo coordinate the lane
102
+ # The fork base: the per-repo coordinate the lane
103
103
  # forked from on its integration branch, recorded ONCE at create and never
104
104
  # recomputed. Each entry is {branch: <integration branch, e.g. dev>, sha: <its
105
105
  # tip when the lane was cut>}. The reproduction paths (workspace snapshot,
@@ -527,8 +527,8 @@ def record_fork_base(
527
527
  ) -> None:
528
528
  """Record the fork base (the materialization point) into an existing lane doc.
529
529
 
530
- ``create_lane`` records ONLY the fork base the caller supplies (the fork-base
531
- ruling: record, do not derive). The CLI `lane create` clones each repo at its
530
+ ``create_lane`` records ONLY the fork base the caller supplies
531
+ (record, do not derive). The CLI `lane create` clones each repo at its
532
532
  branch AFTER the doc is written, so the materialization point — the branch the
533
533
  lane forked from and the sha it started at — is not known until then; this writes
534
534
  it back. Without it a CLI-created lane has no fork base and `review create-project`
@@ -888,7 +888,7 @@ def _validate_bound_worktree(bind_path: Path, workspace_root: Path) -> tuple[str
888
888
 
889
889
  Containment: the resolved worktree must live UNDER ``workspace_root`` (a plain
890
890
  filesystem containment, same shape as ``close_review_lane``'s strict-descendant
891
- gate). This is the ruling's "a path outside the author's own gripspace"
891
+ gate). This is the "path outside the author's own gripspace"
892
892
  refusal, implemented as a path check rather than via identity resolution — so
893
893
  it needs no owner-unit -> gripspace mapping and stays clear of the premium
894
894
  boundary."""
@@ -934,7 +934,7 @@ def create_lane(args: argparse.Namespace) -> int:
934
934
  if missing:
935
935
  raise SystemExit(f"unknown repos for lane: {', '.join(missing)}")
936
936
 
937
- # gr2-lane-author-shape ruling (2026-09-03): --bind makes the lane a LABEL on
937
+ # By design, --bind makes the lane a LABEL on
938
938
  # an existing worktree instead of a fresh materialization. A bound lane is
939
939
  # single-repo only, and its head/branch come from the worktree under the
940
940
  # clean-tree/HEAD guard; no clone is materialized (no repos/ subdir).
@@ -949,7 +949,7 @@ def create_lane(args: argparse.Namespace) -> int:
949
949
  # missing-mapping error for a repo a bound lane would never carry).
950
950
  if len(repos) != 1:
951
951
  raise SystemExit(
952
- "a bound lane is single-repo only (gr2-lane-author-shape ruling): pass exactly "
952
+ "a bound lane is single-repo only: pass exactly "
953
953
  f"one repo to --repos, got {repos or '[]'}"
954
954
  )
955
955
  head, branch = _validate_bound_worktree(Path(bind), workspace_root)
@@ -962,7 +962,7 @@ def create_lane(args: argparse.Namespace) -> int:
962
962
  else:
963
963
  branch_map = parse_branch_arg(args.branch, repos)
964
964
 
965
- # fork-base ruling: record what the caller supplies, do not derive.
965
+ # Fork base: record what the caller supplies, do not derive.
966
966
  # Each entry names a repo IN the lane and carries a 40-hex integration-branch tip.
967
967
  raw_fork_base = getattr(args, "fork_base", None) or {}
968
968
  fork_base: dict[str, dict[str, str]] = {}
@@ -1045,7 +1045,7 @@ def bind_bound_lane(
1045
1045
  workspace_root: Path, owner_unit: str, lane_name: str, *, base: str | None = None, allow_local: bool = False
1046
1046
  ) -> "_review.ReviewRecord":
1047
1047
  """Bind a review receipt for a BOUND lane, sourced LIVE from the author's
1048
- worktree (gr2-lane-author-shape ruling verb #2).
1048
+ worktree.
1049
1049
 
1050
1050
  A bound lane has no materialized clone and no carried range: its reviewed
1051
1051
  bytes are the author's own worktree, so reconstruction is "read the local
@@ -1076,7 +1076,7 @@ def bind_bound_lane(
1076
1076
  f"bind_bound_lane: lane {owner_unit}/{lane_name} is not a bound lane "
1077
1077
  f"(lane_kind={lane_doc.get('lane_kind')!r}); use the materialized review path"
1078
1078
  )
1079
- # Base resolution (fork-base ruling): an explicit base wins; when omitted, read
1079
+ # Base resolution: an explicit base wins; when omitted, read
1080
1080
  # the recorded fork base for this bound lane's single repo. A lane with neither
1081
1081
  # is refused with the unknown message — the review base is never HEAD^.
1082
1082
  if base is None:
@@ -1152,7 +1152,7 @@ def pr_create_bound_lane(
1152
1152
  set_upstream: bool = True,
1153
1153
  ) -> "_push.PushReceipt":
1154
1154
  """`pr create` for a BOUND lane: push the reviewed head from the author's own
1155
- worktree (gr2-lane-author-shape ruling verb #4).
1155
+ worktree.
1156
1156
 
1157
1157
  A bound lane's PR is opened FROM the worktree, not from a materialized clone,
1158
1158
  so this reuses the ordinary push seam (``push_current_branch``, which verifies
@@ -4,6 +4,7 @@ import argparse
4
4
  import json
5
5
  import os
6
6
  import subprocess
7
+ import sys
7
8
  import tempfile
8
9
  from pathlib import Path
9
10
 
@@ -21,7 +22,7 @@ def run(args: list[str], *, cwd: Path | None = None, check: bool = True) -> subp
21
22
 
22
23
 
23
24
  def pygr2(*args: str, cwd: Path | None = None, check: bool = True) -> subprocess.CompletedProcess[str]:
24
- return run(["python3", "-m", "gr2.python_cli", *args], cwd=cwd, check=check)
25
+ return run([sys.executable, "-m", "gr2.python_cli", *args], cwd=cwd, check=check)
25
26
 
26
27
 
27
28
  def git(*args: str, cwd: Path | None = None, check: bool = True) -> subprocess.CompletedProcess[str]:
@@ -4,6 +4,7 @@ import argparse
4
4
  import json
5
5
  import os
6
6
  import subprocess
7
+ import sys
7
8
  import tempfile
8
9
  from pathlib import Path
9
10
 
@@ -21,7 +22,7 @@ def run(args: list[str], *, cwd: Path | None = None, check: bool = True) -> subp
21
22
 
22
23
 
23
24
  def pygr2(*args: str, cwd: Path | None = None, check: bool = True) -> subprocess.CompletedProcess[str]:
24
- return run(["python3", "-m", "gr2.python_cli", *args], cwd=cwd, check=check)
25
+ return run([sys.executable, "-m", "gr2.python_cli", *args], cwd=cwd, check=check)
25
26
 
26
27
 
27
28
  def git(*args: str, cwd: Path | None = None, check: bool = True) -> subprocess.CompletedProcess[str]:
@@ -3,6 +3,7 @@ from __future__ import annotations
3
3
  import argparse
4
4
  import json
5
5
  import os
6
+ import sys
6
7
  import tempfile
7
8
  from pathlib import Path
8
9
  import subprocess
@@ -21,7 +22,7 @@ def run(args: list[str], *, cwd: Path | None = None, check: bool = True) -> subp
21
22
 
22
23
 
23
24
  def pygr2(*args: str, cwd: Path | None = None, check: bool = True) -> subprocess.CompletedProcess[str]:
24
- return run(["python3", "-m", "gr2.python_cli", *args], cwd=cwd, check=check)
25
+ return run([sys.executable, "-m", "gr2.python_cli", *args], cwd=cwd, check=check)
25
26
 
26
27
 
27
28
  def write_gr1_workspace(workspace_root: Path) -> None:
@@ -4,6 +4,7 @@ import argparse
4
4
  import json
5
5
  import os
6
6
  import subprocess
7
+ import sys
7
8
  import tempfile
8
9
  import tomllib
9
10
  from pathlib import Path
@@ -22,7 +23,7 @@ def run(args: list[str], *, cwd: Path | None = None, check: bool = True) -> subp
22
23
 
23
24
 
24
25
  def pygr2(*args: str, cwd: Path | None = None, check: bool = True) -> subprocess.CompletedProcess[str]:
25
- return run(["python3", "-m", "gr2.python_cli", *args], cwd=cwd, check=check)
26
+ return run([sys.executable, "-m", "gr2.python_cli", *args], cwd=cwd, check=check)
26
27
 
27
28
 
28
29
  def git(*args: str, cwd: Path | None = None, check: bool = True) -> subprocess.CompletedProcess[str]:
@@ -5,6 +5,7 @@ import json
5
5
  import os
6
6
  import shutil
7
7
  import subprocess
8
+ import sys
8
9
  import tempfile
9
10
  from pathlib import Path
10
11
 
@@ -22,7 +23,7 @@ def run(args: list[str], *, cwd: Path | None = None, check: bool = True) -> subp
22
23
 
23
24
 
24
25
  def pygr2(*args: str, cwd: Path | None = None, check: bool = True) -> subprocess.CompletedProcess[str]:
25
- return run(["python3", "-m", "gr2.python_cli", *args], cwd=cwd, check=check)
26
+ return run([sys.executable, "-m", "gr2.python_cli", *args], cwd=cwd, check=check)
26
27
 
27
28
 
28
29
  def git(*args: str, cwd: Path | None = None, check: bool = True) -> subprocess.CompletedProcess[str]:
@@ -7,6 +7,7 @@ import argparse
7
7
  import json
8
8
  import shutil
9
9
  import subprocess
10
+ import sys
10
11
  import tempfile
11
12
  from pathlib import Path
12
13
 
@@ -99,7 +100,7 @@ def create_lane(
99
100
  ) -> None:
100
101
  run(
101
102
  [
102
- "python3",
103
+ sys.executable,
103
104
  str(lane_proto(root)),
104
105
  "create-lane",
105
106
  str(workspace_root),
@@ -118,7 +119,7 @@ def plan_exec_json(
118
119
  ) -> list[dict]:
119
120
  proc = run(
120
121
  [
121
- "python3",
122
+ sys.executable,
122
123
  str(lane_proto(root)),
123
124
  "plan-exec",
124
125
  str(workspace_root),
@@ -60,7 +60,7 @@ def run(args: list[str], *, cwd: Path | None = None, check: bool = True) -> subp
60
60
 
61
61
 
62
62
  def pygr2(*args: str, cwd: Path | None = None, check: bool = True) -> subprocess.CompletedProcess[str]:
63
- return run(["python3", "-m", "gr2.python_cli", *args], cwd=cwd, check=check)
63
+ return run([sys.executable, "-m", "gr2.python_cli", *args], cwd=cwd, check=check)
64
64
 
65
65
 
66
66
  def git(*args: str, cwd: Path | None = None, check: bool = True) -> subprocess.CompletedProcess[str]:
@@ -1,19 +1,17 @@
1
1
  [build-system]
2
2
  requires = ["setuptools>=68.0"]
3
- # In-tree backend (gr2/_build/backend.py): single-sources the version from the
4
- # repo-root Cargo.toml at build time so a published wheel says which grip it
5
- # belongs to, instead of a hand-maintained number drifting from the Rust crate.
6
- build-backend = "backend"
7
- backend-path = ["_build"]
3
+ build-backend = "setuptools.build_meta"
8
4
 
9
5
  [project]
10
6
  # One product name across both indexes: `cargo install gitgrip` gives `gr`,
11
7
  # `pip install gitgrip` gives `gr2` (the console script below). The import
12
8
  # package is `gr2`; `gr2_overlay` survives only as a deprecated compat shim.
13
9
  name = "gitgrip"
14
- # Single-sourced from Cargo.toml at build time (see [build-system] backend and
15
- # [tool.setuptools.dynamic] below); never hand-edited here.
16
- dynamic = ["version"]
10
+ # gr2 versions independently of the Rust crate: the Python distribution owns this
11
+ # number and it is not derived from Cargo.toml. gr1 releases as crates.io/GitHub
12
+ # `v1.x.y`; gr2 releases as PyPI `gr2/v2.x.y`. Runtime reads it via
13
+ # importlib.metadata.version("gitgrip"), never a checked-in file.
14
+ version = "2.0.0a1"
17
15
  description = "gr2 overlay substrate: config-overlay capture, composition, and materialization"
18
16
  requires-python = ">=3.11"
19
17
  dependencies = [
@@ -29,6 +27,7 @@ dependencies = [
29
27
 
30
28
  [project.scripts]
31
29
  gr2 = "gr2.python_cli.app:main"
30
+ git-review = "gr2.python_cli.git_review:main"
32
31
 
33
32
  [project.optional-dependencies]
34
33
  dev = [
@@ -36,11 +35,6 @@ dev = [
36
35
  "ruff>=0.4",
37
36
  ]
38
37
 
39
- [tool.setuptools.dynamic]
40
- # VERSION is generated at build time by _build/backend.py from ../Cargo.toml; it
41
- # is gitignored and travels inside the sdist (MANIFEST.in) for wheel-from-sdist.
42
- version = { file = "VERSION" }
43
-
44
38
  [tool.setuptools]
45
39
  # The overlay subsystem is `gr2.overlay` (physically gr2/overlay). `gr2_overlay`
46
40
  # is a deprecated top-level compat shim that aliases every submodule through