gitgrip 2.0.0a9__tar.gz → 2.0.0a10__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.
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/PKG-INFO +59 -11
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/README.md +57 -10
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gitgrip.egg-info/PKG-INFO +59 -11
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gitgrip.egg-info/SOURCES.txt +72 -3
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gitgrip.egg-info/requires.txt +1 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/PLATFORM_ADAPTER_CHANGELOG.md +16 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/prototypes/lane_workspace_prototype.py +25 -3
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/prototypes/repo_maintenance_prototype.py +5 -21
- gitgrip-2.0.0a10/gr2/python_cli/_build.json +1 -0
- gitgrip-2.0.0a10/gr2/python_cli/add.py +104 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/app.py +746 -125
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/approvals.py +222 -12
- gitgrip-2.0.0a10/gr2/python_cli/arbon.py +123 -0
- gitgrip-2.0.0a10/gr2/python_cli/branch_update.py +115 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/clone_exec.py +75 -1
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/consent.py +20 -17
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/defaults.py +21 -0
- gitgrip-2.0.0a10/gr2/python_cli/delete.py +62 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/gitops.py +41 -4
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/grip.py +461 -25
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/grip_cli.py +833 -71
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/lane_downstream.py +53 -8
- gitgrip-2.0.0a10/gr2/python_cli/leased_push.py +79 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/merge_gate.py +216 -14
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/migration.py +118 -215
- gitgrip-2.0.0a10/gr2/python_cli/next_steps.py +215 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/open_gr_review.py +3 -17
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/platform.py +51 -0
- gitgrip-2.0.0a10/gr2/python_cli/proto_json.py +122 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/review.py +55 -0
- gitgrip-2.0.0a10/gr2/python_cli/review_diff.py +88 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/review_ephemeral.py +34 -6
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/review_field_tree.py +7 -3
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/review_rebind.py +12 -0
- gitgrip-2.0.0a10/gr2/python_cli/review_update.py +176 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/set_check.py +36 -2
- gitgrip-2.0.0a10/gr2/python_cli/shadow.py +190 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/spec_apply.py +66 -9
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/store_hooks.py +29 -12
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/syncops.py +11 -6
- gitgrip-2.0.0a10/gr2/python_cli/tracking.py +54 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/version.py +54 -7
- gitgrip-2.0.0a10/gr2/python_cli/workspace_guidance.py +74 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/schemas/dev.synapt.grip.review.v1alpha1/descriptor_set.pb +4 -3
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/schemas/dev.synapt.grip.review.v1alpha1/review.proto +1 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/pyproject.toml +4 -1
- gitgrip-2.0.0a10/setup.py +123 -0
- gitgrip-2.0.0a10/tests/test_add.py +276 -0
- gitgrip-2.0.0a10/tests/test_add_lane_from_a_subdirectory.py +87 -0
- gitgrip-2.0.0a10/tests/test_arbon.py +230 -0
- gitgrip-2.0.0a10/tests/test_bind_merge_head_refusals.py +116 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_break_18_gr1_sibling_units.py +45 -30
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_clone_materialization.py +130 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_declared_sets.py +1 -1
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_defaults_from_repo.py +55 -18
- gitgrip-2.0.0a10/tests/test_delete.py +157 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_event_outcome_policy.py +2 -1
- gitgrip-2.0.0a10/tests/test_fetch_refmap.py +70 -0
- gitgrip-2.0.0a10/tests/test_fetch_refmap_pr_base.py +84 -0
- gitgrip-2.0.0a10/tests/test_gitops_locating_env.py +109 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_gitops_shared.py +7 -3
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_gr_installed_wheel.py +9 -3
- gitgrip-2.0.0a10/tests/test_init_advice_never_nests.py +191 -0
- gitgrip-2.0.0a10/tests/test_lane_cache_keyed_by_member_name.py +144 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_lane_create_defaults.py +104 -5
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_lane_exit_keeps_dirty_work.py +53 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_lane_remove.py +131 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_lane_store_path_pins.py +16 -14
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_layout_census.py +1 -1
- gitgrip-2.0.0a10/tests/test_leased_push.py +166 -0
- gitgrip-2.0.0a10/tests/test_merge_credential_remotes.py +84 -0
- gitgrip-2.0.0a10/tests/test_migrate_gr1_one_root.py +247 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_migration.py +3 -1
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_np_bench_contract_scenario.py +1 -1
- gitgrip-2.0.0a10/tests/test_one_pin_record.py +399 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_out_of_set_hint.py +3 -3
- gitgrip-2.0.0a10/tests/test_outside_names_as_git_options.py +272 -0
- gitgrip-2.0.0a10/tests/test_pr_create_pins_itself.py +279 -0
- gitgrip-2.0.0a10/tests/test_proto_json.py +145 -0
- gitgrip-2.0.0a10/tests/test_readme_walk.py +169 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_record_schema_copies.py +4 -4
- gitgrip-2.0.0a10/tests/test_refusal_names_the_cause.py +138 -0
- gitgrip-2.0.0a10/tests/test_repo_maintenance_gitops.py +109 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_a4_v3.py +17 -5
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_approvals.py +216 -15
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_bind_verify.py +8 -5
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_cli.py +5 -4
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_close_keeps_local_work.py +3 -1
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_field_tree.py +1 -1
- gitgrip-2.0.0a10/tests/test_review_json_refusals.py +74 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_merge_gate.py +26 -10
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_merge_gate_lost_ack.py +8 -5
- gitgrip-2.0.0a10/tests/test_review_merge_platform.py +344 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_merge_receipt.py +6 -3
- gitgrip-2.0.0a10/tests/test_review_merge_set_alone.py +197 -0
- gitgrip-2.0.0a10/tests/test_review_merge_set_required.py +244 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_merge_updates_tracking_ref.py +2 -2
- gitgrip-2.0.0a10/tests/test_review_named_refusals.py +53 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_open_lane.py +262 -0
- gitgrip-2.0.0a10/tests/test_review_open_reader_lane.py +179 -0
- gitgrip-2.0.0a10/tests/test_review_pin_after_push.py +266 -0
- gitgrip-2.0.0a10/tests/test_review_pin_ratified.py +126 -0
- gitgrip-2.0.0a10/tests/test_review_pin_rows_json_help.py +27 -0
- gitgrip-2.0.0a10/tests/test_review_pinned_target.py +207 -0
- gitgrip-2.0.0a10/tests/test_review_publish_all.py +292 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_reader_defaults.py +1 -1
- gitgrip-2.0.0a10/tests/test_review_receive_no_migrate.py +61 -0
- gitgrip-2.0.0a10/tests/test_review_show_diff.py +464 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_transport.py +156 -1
- gitgrip-2.0.0a10/tests/test_review_update.py +378 -0
- gitgrip-2.0.0a10/tests/test_review_verify_json_refusals.py +97 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_root_option_verbs.py +1 -1
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_set_check.py +66 -5
- gitgrip-2.0.0a10/tests/test_set_check_credential_remote.py +34 -0
- gitgrip-2.0.0a10/tests/test_set_check_merge_head.py +138 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_set_check_remote_heads.py +7 -5
- gitgrip-2.0.0a10/tests/test_shadow.py +163 -0
- gitgrip-2.0.0a10/tests/test_shadow_lease.py +178 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_skill_dump.py +4 -3
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_store_break_attempts.py +3 -0
- gitgrip-2.0.0a10/tests/test_store_check_undeclared_gitlink.py +121 -0
- gitgrip-2.0.0a10/tests/test_store_commit_compat_next_step.py +139 -0
- gitgrip-2.0.0a10/tests/test_store_fence_no_pin.py +61 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_store_full_mode_carrier.py +4 -1
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_store_full_mode_layers.py +7 -3
- gitgrip-2.0.0a10/tests/test_store_init_derived_spec.py +170 -0
- gitgrip-2.0.0a10/tests/test_store_init_slot_pointer.py +127 -0
- gitgrip-2.0.0a10/tests/test_store_init_slot_write_error.py +78 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_store_member_state.py +6 -1
- gitgrip-2.0.0a10/tests/test_store_push_landed_by_another.py +64 -0
- gitgrip-2.0.0a10/tests/test_store_push_member_refs.py +166 -0
- gitgrip-2.0.0a10/tests/test_store_push_s2.py +176 -0
- gitgrip-2.0.0a10/tests/test_store_push_s3a.py +246 -0
- gitgrip-2.0.0a10/tests/test_store_push_s3b.py +295 -0
- gitgrip-2.0.0a10/tests/test_store_refusal_names_both_exits.py +76 -0
- gitgrip-2.0.0a10/tests/test_store_shadow_fence.py +175 -0
- gitgrip-2.0.0a10/tests/test_store_shadow_s1.py +142 -0
- gitgrip-2.0.0a10/tests/test_store_status_push_undeclared_gitlink.py +92 -0
- gitgrip-2.0.0a10/tests/test_store_untracked_member.py +99 -0
- gitgrip-2.0.0a10/tests/test_store_verbs_name_their_root.py +236 -0
- gitgrip-2.0.0a10/tests/test_subdir_cwd_review_verbs.py +79 -0
- gitgrip-2.0.0a10/tests/test_subdir_cwd_verbs.py +91 -0
- gitgrip-2.0.0a10/tests/test_tracking.py +144 -0
- gitgrip-2.0.0a10/tests/test_update.py +385 -0
- gitgrip-2.0.0a10/tests/test_version_build_stamp.py +393 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_version_identity.py +35 -3
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_version_static.py +8 -4
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_workspace_identity_boundary.py +9 -7
- gitgrip-2.0.0a10/tests/test_workspace_spec_missing.py +118 -0
- gitgrip-2.0.0a9/gr2/python_cli/add.py +0 -51
- gitgrip-2.0.0a9/gr2/python_cli/next_steps.py +0 -101
- gitgrip-2.0.0a9/gr2/python_cli/workspace_guidance.py +0 -22
- gitgrip-2.0.0a9/tests/test_add.py +0 -129
- gitgrip-2.0.0a9/tests/test_migration_desk_state.py +0 -512
- gitgrip-2.0.0a9/tests/test_migration_unadopted_notice.py +0 -134
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gitgrip.egg-info/dependency_links.txt +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gitgrip.egg-info/entry_points.txt +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gitgrip.egg-info/top_level.txt +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/__init__.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/api_core.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/overlay/__init__.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/overlay/activate.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/overlay/agent_manifest.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/overlay/cli.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/overlay/cross_repo.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/overlay/drivers.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/overlay/introspection.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/overlay/language_drivers.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/overlay/objects.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/overlay/perf.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/overlay/refs.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/overlay/trust.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/overlay/types.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/overlay/units.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/overlay/workspace_spec.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/prototypes/__init__.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/prototypes/cache_materialization_probe.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/prototypes/concurrent_event_stress.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/prototypes/concurrent_lease_stress.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/prototypes/concurrent_workspace_cap_stress.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/prototypes/contribution_protocol.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/prototypes/cross_mode_lane_stress.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/prototypes/jsonl_store.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/prototypes/layout_model_probe.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/prototypes/propagation_daemon.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/prototypes/propagation_state_machine.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/prototypes/python_exec_playground.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/prototypes/python_hook_runtime_playground.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/prototypes/python_migration_playground.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/prototypes/python_review_checkout_playground.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/prototypes/python_spec_apply_playground.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/prototypes/real_git_lane_materialization.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/prototypes/real_git_playground.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/prototypes/recall_lane_history.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/prototypes/repo_transport_probe.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/__init__.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/__main__.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/agent_record.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/approval_schema.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/branch.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/channel_bridge.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/check_records.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/commit.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/config.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/context.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/declared_sets.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/ecosystems_python.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/env_exec.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/events.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/execops.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/exit_codes.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/failures.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/file_exec.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/git_review.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/gitinclude.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/gr_resolver.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/gr_shadow.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/hooks.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/lane_defaults.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/lane_graph.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/lane_plugins.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/launch_exec.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/layout.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/member_field_tree.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/merge_receipts.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/merge_verification.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/names.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/pr.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/project_review.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/prune.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/push.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/review_allocation.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/review_dispatch.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/review_members.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/review_records.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/review_run.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/review_runners.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/root_option.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/set_hints.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/staging_cleanup.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/target.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/workspace_mode.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/python_cli/workspace_snapshot.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/schemas/dev.synapt.grip.approval.v1alpha1/approval.proto +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/schemas/dev.synapt.grip.approval.v1alpha1/descriptor_set.pb +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/schemas/dev.synapt.grip.check.v1alpha1/check.proto +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/schemas/dev.synapt.grip.check.v1alpha1/descriptor_set.pb +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/schemas/dev.synapt.grip.merge.v1alpha1/descriptor_set.pb +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/schemas/dev.synapt.grip.merge.v1alpha1/merge.proto +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/schemas/gr2-materialization-plan-v1.schema.json +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2/schemas/gr2-workspace-spec-v1.schema.json +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/gr2_overlay/__init__.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/setup.cfg +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_agent_manifest_overlay_source.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_agent_record_append.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_agent_record_fold.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_agent_record_stamps.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_api_core_seam.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_api_dump.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_app_event_outcomes.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_apply_convergence.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_apply_gr1_sibling_adoption.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_approval_schema.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_branch.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_break_17_unit_path_containment.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_channel_bridge.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_cli_adapter_error_boundary.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_cli_shape_witnesses.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_commit.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_config_base_path_guard.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_config_overlay.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_conftest_git_isolation.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_consent_key_paths.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_context_resolver.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_contribution_protocol.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_declared_set_pins.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_deprecation_registry.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_ecosystems_python.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_ensure_lane_checkout_reference_clone.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_env_materialization.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_event_log_integrity.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_events.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_events_torn_line.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_exec_apostrophe_and_oserror.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_exec_run_names_what_did_not_run.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_exec_single_string_and_materialize_plan.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_execops.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_failure_event_outcome.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_field_tree_name.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_field_tree_schema_reader.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_files_compose.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_first_five_minutes.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_foreground_launch_runtime.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_git_review.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_git_transport_allow_list.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_gitinclude_compiler.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_gr1_first_run_guidance.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_gr2_packaging.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_gr2_review_receipt.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_gr_resolved_cleared.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_gr_resolver_conformance.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_gr_shadow.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_grip_cli.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_grip_hardening.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_grip_snapshot.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_grip_toml_literals.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_grip_toml_schema_v1.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_hook_events.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_hook_hardening.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_hooks_consent.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_hooks_group_names.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_hostile_names.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_hostile_names_helper.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_jsonl_store.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_lane_checkout_root.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_lane_create_fork_base_cli.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_lane_create_refusal_leaves_nothing.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_lane_create_refuses_own_branch.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_lane_downstream.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_lane_downstream_run.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_lane_enter_hook_warnings.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_lane_graph.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_lane_lease_show_json.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_lane_lifecycle_safety.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_lane_plugins.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_lane_probe.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_lane_probe_batch.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_lane_push.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_lane_repo_paths_and_all_skipped.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_lane_roles.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_lane_show_name.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_lane_toml_serialization.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_launch_primitive.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_linked_review_receipts.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_m2_overlay_hindsight.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_m2_overlay_mem0.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_m2_overlay_zep.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_malformed_remote_refusal.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_materialization_plan_contract.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_materialize_pin.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_member_working_root_checkout_materialize.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_merge_evidence.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_merge_parent_verification.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_migration_overlay_compatibility.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_names.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_native_store_gitinclude.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_native_store_review_record_probes.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_no_bare_python_cli_imports.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_null_current_lane_refusal.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_open_gr_enter.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_open_project_refusal_reason_cli.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_outbox_ack_after_effect.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_overlay_acceptance.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_overlay_activate.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_overlay_cli.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_overlay_cli_wiring.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_overlay_composition_merge.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_overlay_cross_repo_atomic_apply.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_overlay_cross_repo_perf_gate.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_overlay_cross_repo_rollback.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_overlay_driver_registry.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_overlay_introspection.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_overlay_multi_stack.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_overlay_object_encoding.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_overlay_perf_gates.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_overlay_python_driver.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_overlay_tier_b_encoding.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_overlay_tier_b_perf_gates.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_overlay_tier_b_repo_state.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_overlay_tier_b_staging_discipline.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_overlay_trust_model.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_overlay_workspace_spec.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_platform_adapter_changelog.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_platform_adapter_plugins.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_pr_adapter_v2_target.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_pr_events.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_pr_group_legibility.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_pr_merge_head_pin.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_pr_merge_method.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_pr_merge_missing_target.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_pr_merge_partial_failure.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_pr_review_subject.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_pr_view.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_project_file_materialization.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_project_review_range_reconstruction.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_project_review_three_repo.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_projection_tracked_dest.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_propagation_contribution.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_propagation_daemon.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_propagation_state_machine.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_prune.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_push.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_python_group_install.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_readme_verbs_exist.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_remote_check_records.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_repo_path_read_through.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_repo_status_linked_worktree.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_repo_status_schema_version.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_repo_status_symlinked_git_dir.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_retire_gr1.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_a4.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_a4_v2.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_allocation_recovery.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_ansi_parse.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_b3_reader_alignment.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_bind_author.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_bind_fork_base.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_bind_from_range.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_bind_migration.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_bind_native_store.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_bind_root_refs.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_check_name.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_close_gr.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_context_defaults.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_context_witnesses.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_create_project_cli.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_dispatch.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_ephemeral.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_events.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_field_tree_reader_edges.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_field_tree_readers.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_install_hint.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_pin_stamp_names.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_pr_marker_context.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_rebind.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_receipt_cleanup.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_ref_v1_migration.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_ref_v1_reader.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_ref_v1_writer.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_remote_safety.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_run.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_run_context.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_run_deleted_cwd.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_run_dependency_order.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_run_import_isolation.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_run_integrity_recheck.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_run_multi_repo.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_run_package_name.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_run_plugin_order.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_run_rerun_and_refusal_receipt.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_run_venv_and_refusal_identity.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_runners.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_subject.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_v1_format_guard.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_verify_inside.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_review_vocabulary.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_rmtree_or_refuse.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_selected_workspace_commit.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_single_repo_cwd_refusal.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_snapshot_id_prefix_resolution.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_spec_apply_event_outcomes.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_spec_declaration_ref_pin.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_spec_show_native_root.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_sprint21_sync_platform.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_staging_cleanup.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_store_checkout_atomicity.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_store_commit_follows_branch.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_store_commit_keeps_record.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_store_commit_noop.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_store_commit_refuses_rewind.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_store_declared_members.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_store_full_mode_coverage.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_store_full_mode_records.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_store_git_hooks.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_store_git_native_smoke.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_store_gitmodules.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_store_gitmodules_branch.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_store_hook_takes_verb_coverage.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_store_init_branch_inference.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_store_init_clone.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_store_log_adoption_boundary.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_store_materialize_branch.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_store_materialize_fetches_new_pin.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_store_materialize_installs_hooks.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_store_member_path_hygiene.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_store_migrate_branch_inference.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_store_moved_workspace_guard.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_store_status_inspection.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_store_status_values.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_store_submodule_init.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_store_submodule_update_merge.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_store_verb_rename.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_store_verb_witnesses.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_submodule_member_predicate.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_superproject_import.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_sync_event_outcomes.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_sync_fast_forward.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_sync_fetch.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_sync_seed_local.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_sync_ssh_rewrite.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_sync_status_probe.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_target.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_tmux_launch_runtime.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_unit_abort.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_unit_apply.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_unit_apply_dry_run.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_unit_manifest_schema.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_unit_propose.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_unit_topological_apply.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_validate_repo_path_conflict.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_vocabulary.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_workspace_convert_clone.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_workspace_edit_lease_cap.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_workspace_init_from_topology.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_workspace_init_local_repos.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_workspace_root_defaults.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_workspace_root_nearest_marker.py +0 -0
- {gitgrip-2.0.0a9 → gitgrip-2.0.0a10}/tests/test_workspace_snapshot.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gitgrip
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.0a10
|
|
4
4
|
Summary: Workspace layer for multi-repo work: workspaces, isolated lanes, and one grouped review per slice
|
|
5
5
|
Requires-Python: >=3.11
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
@@ -13,6 +13,7 @@ Provides-Extra: dev
|
|
|
13
13
|
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
14
14
|
Requires-Dist: ruff>=0.4; extra == "dev"
|
|
15
15
|
Requires-Dist: packaging>=22; extra == "dev"
|
|
16
|
+
Requires-Dist: setuptools>=68.0; extra == "dev"
|
|
16
17
|
|
|
17
18
|
# gr2
|
|
18
19
|
|
|
@@ -51,8 +52,11 @@ gr2 workspace init ~/ws # scans the folder; writes .grip/workspa
|
|
|
51
52
|
gr2 workspace materialize ~/ws --yes # builds the .grip layout and a default unit
|
|
52
53
|
gr2 workspace status ~/ws # what kind of workspace this is
|
|
53
54
|
gr2 store init ~/ws # the workspace snapshot store (needed before review)
|
|
55
|
+
gr2 store commit -m "first snapshot" # record the workspace once; lanes start from a recorded snapshot
|
|
54
56
|
```
|
|
55
57
|
|
|
58
|
+
`store commit` reads the workspace from the current directory, which is why the walk starts with `cd ~/ws`; from anywhere else, name it: `gr2 store commit -C ~/ws -m "..."`. It prints nothing on success; each repo it records for the first time gets one note on stderr.
|
|
59
|
+
|
|
56
60
|
A **unit** is one worker — you, or one agent — and `default` is created for you. A **lane** is one piece of work spanning repos, with its own clones, so two lanes never step on each other:
|
|
57
61
|
|
|
58
62
|
```bash
|
|
@@ -60,24 +64,25 @@ gr2 lane create ~/ws default feat-x --repos repo-a,repo-b --branch feat/x
|
|
|
60
64
|
gr2 lane enter ~/ws default feat-x --actor human:you
|
|
61
65
|
```
|
|
62
66
|
|
|
63
|
-
|
|
67
|
+
`lane create` prints the lane's record, then, per repo, the absolute directory you work in (`lane enter` prints the same directories as `repo_paths`):
|
|
64
68
|
|
|
65
69
|
```
|
|
66
|
-
|
|
67
|
-
repo-
|
|
70
|
+
~/ws/.grip/state/lanes/default/feat-x/lane.toml
|
|
71
|
+
repo-a: ~/ws/agents/default/lanes/feat-x/repo-a
|
|
72
|
+
repo-b: ~/ws/agents/default/lanes/feat-x/repo-b
|
|
68
73
|
```
|
|
69
74
|
|
|
70
75
|
Edit there — not in your original clones. Stage and commit across the lane's repos:
|
|
71
76
|
|
|
72
77
|
```bash
|
|
73
|
-
gr2 add . --repo-path ~/ws
|
|
78
|
+
gr2 add . --repo-path ~/ws/agents/default/lanes/feat-x/repo-a
|
|
74
79
|
gr2 commit -m "my change" --workspace-root ~/ws --owner-unit default
|
|
75
80
|
```
|
|
76
81
|
|
|
77
82
|
`commit` with the lane flags commits every lane repo that has staged changes and names the repos it skipped. If every repo was skipped it exits non-zero with one sentence naming where it looked — and, when it can see them, where your staged changes actually are. Run one command across every lane repo, then turn the lane into one reviewable object:
|
|
78
83
|
|
|
79
84
|
```bash
|
|
80
|
-
gr2 exec run ~/ws default --actor human:you --
|
|
85
|
+
gr2 exec run ~/ws default --actor human:you -- git status --short # one command, every lane repo
|
|
81
86
|
gr2 review create-project ~/ws default feat-x # prints gr:<sha>: one object to review
|
|
82
87
|
gr2 lane push ~/ws default feat-x # push every lane repo, each verified on its remote
|
|
83
88
|
gr2 lane show ~/ws default # where am I?
|
|
@@ -86,7 +91,7 @@ gr2 lane list ~/ws # each lane: removabl
|
|
|
86
91
|
gr2 lane remove ~/ws default feat-x # end it: its clones and record go
|
|
87
92
|
```
|
|
88
93
|
|
|
89
|
-
`lane remove` refuses while the lane is entered or leased, or was made by `lane bind`, while any of its repos holds uncommitted work, a stash, or a commit no remote has (on any branch or tag), or while its checkout holds anything that is not one of its repos; it names each one and removes nothing. `exec run` and `lane exit` require `--actor`. Every group and verb takes `--help`; `gr2 --help` lists them all.
|
|
94
|
+
`lane remove` refuses while the lane is entered or leased, or was made by `lane bind`, while any of its repos holds uncommitted work, a stash, or a commit no remote has (on any branch or tag), or while its checkout holds anything that is not one of its repos; it names each one and removes nothing. `exec run` runs whatever follows `--` in each lane repo, with your own `PATH`: a test runner works there only if it is installed where your shell finds it. `review create-project` refuses a lane repo holding any uncommitted or untracked file, so whatever a command leaves behind (`__pycache__/` after a pytest run, say) has to be in the repo's `.gitignore`. `exec run` and `lane exit` require `--actor`. Every group and verb takes `--help`; `gr2 --help` lists them all.
|
|
90
95
|
|
|
91
96
|
## What works today, and what is not there yet
|
|
92
97
|
|
|
@@ -109,17 +114,20 @@ Not there yet:
|
|
|
109
114
|
| `workspace` | init, init-from-topology, materialize, status, convert-clone, detect-gr1, migrate-gr1, retire-gr1, migrate-lane-state, bootstrap-gr1, gitinclude |
|
|
110
115
|
| `spec` | show, validate |
|
|
111
116
|
| `lane` | create, enter, exit, show, resolve, bind, lease, list, push, remove |
|
|
112
|
-
| (top level) | branch, add, commit, push, prune, status, plan, apply |
|
|
117
|
+
| (top level) | branch, add, commit, push, prune, status, plan, apply, update |
|
|
113
118
|
| `sync` | status, run |
|
|
114
119
|
| `pr` | create, status, checks, merge, view |
|
|
115
120
|
| `check` | run, show, set |
|
|
116
|
-
| `
|
|
121
|
+
| `proto` | json |
|
|
122
|
+
| `review` | open, close, checkout-pr, run, check, pin, publish, receive, verify, show, stamp, merge, update, repin, create-project, bind, approve, rebind |
|
|
117
123
|
| `exec` | status, run |
|
|
118
124
|
| `repo` | status, projection-run |
|
|
119
125
|
| `hooks` | trust, revoke, status, show, run |
|
|
120
126
|
| `store` | init, commit, check, push, status, log, diff, checkout, materialize, migrate, migrate-reviews |
|
|
121
127
|
| `target`, `config` | stored PR target; config overlays |
|
|
122
128
|
|
|
129
|
+
Every `store` verb names its workspace with `-C/--root <root>`, else reads the current directory.
|
|
130
|
+
|
|
123
131
|
`review bind`, `review approve` and `review rebind` remain as aliases of `pin`, `stamp` and `repin`.
|
|
124
132
|
|
|
125
133
|
The words these commands use (lane, pin, stamp, repin, gate, review) are defined in [docs/GLOSSARY.md](docs/GLOSSARY.md).
|
|
@@ -134,6 +142,18 @@ gr2 review stamp
|
|
|
134
142
|
gr2 review merge
|
|
135
143
|
```
|
|
136
144
|
|
|
145
|
+
A reviewer whose own workspace does not hold the reviewed repos (another team's
|
|
146
|
+
gripspace) receives the review, opens a lane, and stamps from the lane (or from one
|
|
147
|
+
repo directory in it). The stamp uses the store of the workspace the lane was opened
|
|
148
|
+
from and the repos checked out in the lane, and records the git `user.name` of that
|
|
149
|
+
workspace, not of the lane:
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
gr2 review receive <their-workspace> gr:<id> --remote <member-remote>
|
|
153
|
+
gr2 review open <their-workspace> gr:<id> --lane-dir <lane>
|
|
154
|
+
gr2 review stamp <lane>
|
|
155
|
+
```
|
|
156
|
+
|
|
137
157
|
The author recorded by the pin, and anyone who authored a commit in its range,
|
|
138
158
|
cannot stamp it. A stamp records an approval; approver names are self-declared and receipts say `signed: false`.
|
|
139
159
|
Repeated stamps by the same name count once. A moved head needs a new pin
|
|
@@ -177,6 +197,18 @@ Set it with `git config user.name 'Your Name'` there if Git has no configured na
|
|
|
177
197
|
`review show --json` and `review verify --json` include this author; older pinned reviews
|
|
178
198
|
remain readable without an author field, and reading them does not invent one.
|
|
179
199
|
|
|
200
|
+
## Run a review's tests
|
|
201
|
+
|
|
202
|
+
`gr2 review run` runs the reviewed tree's tests inside the review's lane, and only after it proves the lane equals the pinned tree. What to install and what to test comes from the reviewed repo itself: a tracked `.review-install` file at the repo root, read whenever the flags are left out. For a Python repo tested with pytest it needs two lines: the package the run must import from inside the lane, and an install that brings pytest:
|
|
203
|
+
|
|
204
|
+
```
|
|
205
|
+
# .review-install
|
|
206
|
+
package = mypkg
|
|
207
|
+
install = {venv} -m pip install -e {lane} pytest
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
`{venv}` is the lane venv's Python executable, not its directory, and `{lane}` is the lane's checkout of the repo; both are filled in per token. Without an `install` line the run uses `<lane venv python> -m pip install -e <lane>`, which installs your package and no test runner, so a pytest repo without the line refuses (`pytest_not_installed`). Either way the repo must be pip-installable (a `pyproject.toml` or `setup.py` declaring that package). For another language, declare the runner and its command instead, for example `runner = cargo` and `test = cargo test`. The recognised keys are `install`, `package`, `runner`, `test` and `reports`; any other key is refused (`bad_hint`). A repo with no `.review-install` must pass `--package` and/or `--install`, and with neither the run refuses (`no_package`). `gr2 review run --help` has the full list.
|
|
211
|
+
|
|
180
212
|
|
|
181
213
|
## Transfer a native review
|
|
182
214
|
|
|
@@ -206,6 +238,13 @@ is refused. Object downloads may remain after refusal. The owned temporary ref
|
|
|
206
238
|
is removed separately, and cleanup failure is reported without replacing a
|
|
207
239
|
primary failure.
|
|
208
240
|
|
|
241
|
+
Receive also fetches each member's pinned head from the remote it read the review
|
|
242
|
+
from, one `heads` row per member. A member whose recorded remote is another one
|
|
243
|
+
(a review published to a staging remote) is `not_this_remote`. `gr2 review open`
|
|
244
|
+
builds the lane from the range the review carries, and the row's `next` names that
|
|
245
|
+
command. `gr2 review show --diff` and `gr2 review stamp` still need the head: they
|
|
246
|
+
refuse until the author pushes it to the member's own remote and it is fetched.
|
|
247
|
+
|
|
209
248
|
The review commit carries its trees, blobs and range patches. It does not make
|
|
210
249
|
its recorded base or original member head reachable as Git parents. Keep each
|
|
211
250
|
member's base reachable at its recorded remote for reconstruction. `verify`
|
|
@@ -260,8 +299,17 @@ observation retains its fields and adds a SHA-256 `observation_id`.
|
|
|
260
299
|
A review over several members is checked as one set. `gr2 check set <workspace> <review> -- <command>`
|
|
261
300
|
reconstructs every member at its pinned head side by side (`GR2_SET_ROOT`, `GR2_REVIEW_ID` and `GR2_SET_MEMBERS`
|
|
262
301
|
name them), runs the command once, and publishes one `set` observation per member remote, carrying the review and the
|
|
263
|
-
identity of the set. `gr2 review merge`
|
|
264
|
-
|
|
302
|
+
identity of the set. With no `--check`, `gr2 review merge` on a multi-member review requires that record AND each
|
|
303
|
+
member's `test` at its head: a member whose recorded `test` is red is refused and nothing lands, and a member with no
|
|
304
|
+
`test` record of its own is decided by the passing set (members that import each other cannot pass a test alone), so
|
|
305
|
+
one `check set` and the approvals are enough to merge. `--check test` names `test` explicitly and only a `test` record
|
|
306
|
+
decides it (one that `check set --name test` wrote for this review counts); its refusal prints that `check set`. On a
|
|
307
|
+
one-member review the default `test` is also decided by a passing `set` record for this review at that head. A `set`
|
|
308
|
+
record for another review or other heads never counts. The requirement comes from the
|
|
309
|
+
review, not from the person merging: on a multi-member review `--no-set` is refused, and so is any `--check` name other
|
|
310
|
+
than `test` and `set`. `review pin` refuses a multi-member review whose rows do not each carry a `source` or a `range`,
|
|
311
|
+
because `check set` could never run on it. `check show --require set --review <id>` reads a `set` record for another
|
|
312
|
+
review as stale.
|
|
265
313
|
|
|
266
314
|
A failed command is recorded and `check run` exits 1. Publication or execution
|
|
267
315
|
refusals exit 2. `check show` returns `pass`, `fail` or `absent` in its JSON;
|
|
@@ -35,8 +35,11 @@ gr2 workspace init ~/ws # scans the folder; writes .grip/workspa
|
|
|
35
35
|
gr2 workspace materialize ~/ws --yes # builds the .grip layout and a default unit
|
|
36
36
|
gr2 workspace status ~/ws # what kind of workspace this is
|
|
37
37
|
gr2 store init ~/ws # the workspace snapshot store (needed before review)
|
|
38
|
+
gr2 store commit -m "first snapshot" # record the workspace once; lanes start from a recorded snapshot
|
|
38
39
|
```
|
|
39
40
|
|
|
41
|
+
`store commit` reads the workspace from the current directory, which is why the walk starts with `cd ~/ws`; from anywhere else, name it: `gr2 store commit -C ~/ws -m "..."`. It prints nothing on success; each repo it records for the first time gets one note on stderr.
|
|
42
|
+
|
|
40
43
|
A **unit** is one worker — you, or one agent — and `default` is created for you. A **lane** is one piece of work spanning repos, with its own clones, so two lanes never step on each other:
|
|
41
44
|
|
|
42
45
|
```bash
|
|
@@ -44,24 +47,25 @@ gr2 lane create ~/ws default feat-x --repos repo-a,repo-b --branch feat/x
|
|
|
44
47
|
gr2 lane enter ~/ws default feat-x --actor human:you
|
|
45
48
|
```
|
|
46
49
|
|
|
47
|
-
|
|
50
|
+
`lane create` prints the lane's record, then, per repo, the absolute directory you work in (`lane enter` prints the same directories as `repo_paths`):
|
|
48
51
|
|
|
49
52
|
```
|
|
50
|
-
|
|
51
|
-
repo-
|
|
53
|
+
~/ws/.grip/state/lanes/default/feat-x/lane.toml
|
|
54
|
+
repo-a: ~/ws/agents/default/lanes/feat-x/repo-a
|
|
55
|
+
repo-b: ~/ws/agents/default/lanes/feat-x/repo-b
|
|
52
56
|
```
|
|
53
57
|
|
|
54
58
|
Edit there — not in your original clones. Stage and commit across the lane's repos:
|
|
55
59
|
|
|
56
60
|
```bash
|
|
57
|
-
gr2 add . --repo-path ~/ws
|
|
61
|
+
gr2 add . --repo-path ~/ws/agents/default/lanes/feat-x/repo-a
|
|
58
62
|
gr2 commit -m "my change" --workspace-root ~/ws --owner-unit default
|
|
59
63
|
```
|
|
60
64
|
|
|
61
65
|
`commit` with the lane flags commits every lane repo that has staged changes and names the repos it skipped. If every repo was skipped it exits non-zero with one sentence naming where it looked — and, when it can see them, where your staged changes actually are. Run one command across every lane repo, then turn the lane into one reviewable object:
|
|
62
66
|
|
|
63
67
|
```bash
|
|
64
|
-
gr2 exec run ~/ws default --actor human:you --
|
|
68
|
+
gr2 exec run ~/ws default --actor human:you -- git status --short # one command, every lane repo
|
|
65
69
|
gr2 review create-project ~/ws default feat-x # prints gr:<sha>: one object to review
|
|
66
70
|
gr2 lane push ~/ws default feat-x # push every lane repo, each verified on its remote
|
|
67
71
|
gr2 lane show ~/ws default # where am I?
|
|
@@ -70,7 +74,7 @@ gr2 lane list ~/ws # each lane: removabl
|
|
|
70
74
|
gr2 lane remove ~/ws default feat-x # end it: its clones and record go
|
|
71
75
|
```
|
|
72
76
|
|
|
73
|
-
`lane remove` refuses while the lane is entered or leased, or was made by `lane bind`, while any of its repos holds uncommitted work, a stash, or a commit no remote has (on any branch or tag), or while its checkout holds anything that is not one of its repos; it names each one and removes nothing. `exec run` and `lane exit` require `--actor`. Every group and verb takes `--help`; `gr2 --help` lists them all.
|
|
77
|
+
`lane remove` refuses while the lane is entered or leased, or was made by `lane bind`, while any of its repos holds uncommitted work, a stash, or a commit no remote has (on any branch or tag), or while its checkout holds anything that is not one of its repos; it names each one and removes nothing. `exec run` runs whatever follows `--` in each lane repo, with your own `PATH`: a test runner works there only if it is installed where your shell finds it. `review create-project` refuses a lane repo holding any uncommitted or untracked file, so whatever a command leaves behind (`__pycache__/` after a pytest run, say) has to be in the repo's `.gitignore`. `exec run` and `lane exit` require `--actor`. Every group and verb takes `--help`; `gr2 --help` lists them all.
|
|
74
78
|
|
|
75
79
|
## What works today, and what is not there yet
|
|
76
80
|
|
|
@@ -93,17 +97,20 @@ Not there yet:
|
|
|
93
97
|
| `workspace` | init, init-from-topology, materialize, status, convert-clone, detect-gr1, migrate-gr1, retire-gr1, migrate-lane-state, bootstrap-gr1, gitinclude |
|
|
94
98
|
| `spec` | show, validate |
|
|
95
99
|
| `lane` | create, enter, exit, show, resolve, bind, lease, list, push, remove |
|
|
96
|
-
| (top level) | branch, add, commit, push, prune, status, plan, apply |
|
|
100
|
+
| (top level) | branch, add, commit, push, prune, status, plan, apply, update |
|
|
97
101
|
| `sync` | status, run |
|
|
98
102
|
| `pr` | create, status, checks, merge, view |
|
|
99
103
|
| `check` | run, show, set |
|
|
100
|
-
| `
|
|
104
|
+
| `proto` | json |
|
|
105
|
+
| `review` | open, close, checkout-pr, run, check, pin, publish, receive, verify, show, stamp, merge, update, repin, create-project, bind, approve, rebind |
|
|
101
106
|
| `exec` | status, run |
|
|
102
107
|
| `repo` | status, projection-run |
|
|
103
108
|
| `hooks` | trust, revoke, status, show, run |
|
|
104
109
|
| `store` | init, commit, check, push, status, log, diff, checkout, materialize, migrate, migrate-reviews |
|
|
105
110
|
| `target`, `config` | stored PR target; config overlays |
|
|
106
111
|
|
|
112
|
+
Every `store` verb names its workspace with `-C/--root <root>`, else reads the current directory.
|
|
113
|
+
|
|
107
114
|
`review bind`, `review approve` and `review rebind` remain as aliases of `pin`, `stamp` and `repin`.
|
|
108
115
|
|
|
109
116
|
The words these commands use (lane, pin, stamp, repin, gate, review) are defined in [docs/GLOSSARY.md](docs/GLOSSARY.md).
|
|
@@ -118,6 +125,18 @@ gr2 review stamp
|
|
|
118
125
|
gr2 review merge
|
|
119
126
|
```
|
|
120
127
|
|
|
128
|
+
A reviewer whose own workspace does not hold the reviewed repos (another team's
|
|
129
|
+
gripspace) receives the review, opens a lane, and stamps from the lane (or from one
|
|
130
|
+
repo directory in it). The stamp uses the store of the workspace the lane was opened
|
|
131
|
+
from and the repos checked out in the lane, and records the git `user.name` of that
|
|
132
|
+
workspace, not of the lane:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
gr2 review receive <their-workspace> gr:<id> --remote <member-remote>
|
|
136
|
+
gr2 review open <their-workspace> gr:<id> --lane-dir <lane>
|
|
137
|
+
gr2 review stamp <lane>
|
|
138
|
+
```
|
|
139
|
+
|
|
121
140
|
The author recorded by the pin, and anyone who authored a commit in its range,
|
|
122
141
|
cannot stamp it. A stamp records an approval; approver names are self-declared and receipts say `signed: false`.
|
|
123
142
|
Repeated stamps by the same name count once. A moved head needs a new pin
|
|
@@ -161,6 +180,18 @@ Set it with `git config user.name 'Your Name'` there if Git has no configured na
|
|
|
161
180
|
`review show --json` and `review verify --json` include this author; older pinned reviews
|
|
162
181
|
remain readable without an author field, and reading them does not invent one.
|
|
163
182
|
|
|
183
|
+
## Run a review's tests
|
|
184
|
+
|
|
185
|
+
`gr2 review run` runs the reviewed tree's tests inside the review's lane, and only after it proves the lane equals the pinned tree. What to install and what to test comes from the reviewed repo itself: a tracked `.review-install` file at the repo root, read whenever the flags are left out. For a Python repo tested with pytest it needs two lines: the package the run must import from inside the lane, and an install that brings pytest:
|
|
186
|
+
|
|
187
|
+
```
|
|
188
|
+
# .review-install
|
|
189
|
+
package = mypkg
|
|
190
|
+
install = {venv} -m pip install -e {lane} pytest
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
`{venv}` is the lane venv's Python executable, not its directory, and `{lane}` is the lane's checkout of the repo; both are filled in per token. Without an `install` line the run uses `<lane venv python> -m pip install -e <lane>`, which installs your package and no test runner, so a pytest repo without the line refuses (`pytest_not_installed`). Either way the repo must be pip-installable (a `pyproject.toml` or `setup.py` declaring that package). For another language, declare the runner and its command instead, for example `runner = cargo` and `test = cargo test`. The recognised keys are `install`, `package`, `runner`, `test` and `reports`; any other key is refused (`bad_hint`). A repo with no `.review-install` must pass `--package` and/or `--install`, and with neither the run refuses (`no_package`). `gr2 review run --help` has the full list.
|
|
194
|
+
|
|
164
195
|
|
|
165
196
|
## Transfer a native review
|
|
166
197
|
|
|
@@ -190,6 +221,13 @@ is refused. Object downloads may remain after refusal. The owned temporary ref
|
|
|
190
221
|
is removed separately, and cleanup failure is reported without replacing a
|
|
191
222
|
primary failure.
|
|
192
223
|
|
|
224
|
+
Receive also fetches each member's pinned head from the remote it read the review
|
|
225
|
+
from, one `heads` row per member. A member whose recorded remote is another one
|
|
226
|
+
(a review published to a staging remote) is `not_this_remote`. `gr2 review open`
|
|
227
|
+
builds the lane from the range the review carries, and the row's `next` names that
|
|
228
|
+
command. `gr2 review show --diff` and `gr2 review stamp` still need the head: they
|
|
229
|
+
refuse until the author pushes it to the member's own remote and it is fetched.
|
|
230
|
+
|
|
193
231
|
The review commit carries its trees, blobs and range patches. It does not make
|
|
194
232
|
its recorded base or original member head reachable as Git parents. Keep each
|
|
195
233
|
member's base reachable at its recorded remote for reconstruction. `verify`
|
|
@@ -244,8 +282,17 @@ observation retains its fields and adds a SHA-256 `observation_id`.
|
|
|
244
282
|
A review over several members is checked as one set. `gr2 check set <workspace> <review> -- <command>`
|
|
245
283
|
reconstructs every member at its pinned head side by side (`GR2_SET_ROOT`, `GR2_REVIEW_ID` and `GR2_SET_MEMBERS`
|
|
246
284
|
name them), runs the command once, and publishes one `set` observation per member remote, carrying the review and the
|
|
247
|
-
identity of the set. `gr2 review merge`
|
|
248
|
-
|
|
285
|
+
identity of the set. With no `--check`, `gr2 review merge` on a multi-member review requires that record AND each
|
|
286
|
+
member's `test` at its head: a member whose recorded `test` is red is refused and nothing lands, and a member with no
|
|
287
|
+
`test` record of its own is decided by the passing set (members that import each other cannot pass a test alone), so
|
|
288
|
+
one `check set` and the approvals are enough to merge. `--check test` names `test` explicitly and only a `test` record
|
|
289
|
+
decides it (one that `check set --name test` wrote for this review counts); its refusal prints that `check set`. On a
|
|
290
|
+
one-member review the default `test` is also decided by a passing `set` record for this review at that head. A `set`
|
|
291
|
+
record for another review or other heads never counts. The requirement comes from the
|
|
292
|
+
review, not from the person merging: on a multi-member review `--no-set` is refused, and so is any `--check` name other
|
|
293
|
+
than `test` and `set`. `review pin` refuses a multi-member review whose rows do not each carry a `source` or a `range`,
|
|
294
|
+
because `check set` could never run on it. `check show --require set --review <id>` reads a `set` record for another
|
|
295
|
+
review as stale.
|
|
249
296
|
|
|
250
297
|
A failed command is recorded and `check run` exits 1. Publication or execution
|
|
251
298
|
refusals exit 2. `check show` returns `pass`, `fail` or `absent` in its JSON;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gitgrip
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.0a10
|
|
4
4
|
Summary: Workspace layer for multi-repo work: workspaces, isolated lanes, and one grouped review per slice
|
|
5
5
|
Requires-Python: >=3.11
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
@@ -13,6 +13,7 @@ Provides-Extra: dev
|
|
|
13
13
|
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
14
14
|
Requires-Dist: ruff>=0.4; extra == "dev"
|
|
15
15
|
Requires-Dist: packaging>=22; extra == "dev"
|
|
16
|
+
Requires-Dist: setuptools>=68.0; extra == "dev"
|
|
16
17
|
|
|
17
18
|
# gr2
|
|
18
19
|
|
|
@@ -51,8 +52,11 @@ gr2 workspace init ~/ws # scans the folder; writes .grip/workspa
|
|
|
51
52
|
gr2 workspace materialize ~/ws --yes # builds the .grip layout and a default unit
|
|
52
53
|
gr2 workspace status ~/ws # what kind of workspace this is
|
|
53
54
|
gr2 store init ~/ws # the workspace snapshot store (needed before review)
|
|
55
|
+
gr2 store commit -m "first snapshot" # record the workspace once; lanes start from a recorded snapshot
|
|
54
56
|
```
|
|
55
57
|
|
|
58
|
+
`store commit` reads the workspace from the current directory, which is why the walk starts with `cd ~/ws`; from anywhere else, name it: `gr2 store commit -C ~/ws -m "..."`. It prints nothing on success; each repo it records for the first time gets one note on stderr.
|
|
59
|
+
|
|
56
60
|
A **unit** is one worker — you, or one agent — and `default` is created for you. A **lane** is one piece of work spanning repos, with its own clones, so two lanes never step on each other:
|
|
57
61
|
|
|
58
62
|
```bash
|
|
@@ -60,24 +64,25 @@ gr2 lane create ~/ws default feat-x --repos repo-a,repo-b --branch feat/x
|
|
|
60
64
|
gr2 lane enter ~/ws default feat-x --actor human:you
|
|
61
65
|
```
|
|
62
66
|
|
|
63
|
-
|
|
67
|
+
`lane create` prints the lane's record, then, per repo, the absolute directory you work in (`lane enter` prints the same directories as `repo_paths`):
|
|
64
68
|
|
|
65
69
|
```
|
|
66
|
-
|
|
67
|
-
repo-
|
|
70
|
+
~/ws/.grip/state/lanes/default/feat-x/lane.toml
|
|
71
|
+
repo-a: ~/ws/agents/default/lanes/feat-x/repo-a
|
|
72
|
+
repo-b: ~/ws/agents/default/lanes/feat-x/repo-b
|
|
68
73
|
```
|
|
69
74
|
|
|
70
75
|
Edit there — not in your original clones. Stage and commit across the lane's repos:
|
|
71
76
|
|
|
72
77
|
```bash
|
|
73
|
-
gr2 add . --repo-path ~/ws
|
|
78
|
+
gr2 add . --repo-path ~/ws/agents/default/lanes/feat-x/repo-a
|
|
74
79
|
gr2 commit -m "my change" --workspace-root ~/ws --owner-unit default
|
|
75
80
|
```
|
|
76
81
|
|
|
77
82
|
`commit` with the lane flags commits every lane repo that has staged changes and names the repos it skipped. If every repo was skipped it exits non-zero with one sentence naming where it looked — and, when it can see them, where your staged changes actually are. Run one command across every lane repo, then turn the lane into one reviewable object:
|
|
78
83
|
|
|
79
84
|
```bash
|
|
80
|
-
gr2 exec run ~/ws default --actor human:you --
|
|
85
|
+
gr2 exec run ~/ws default --actor human:you -- git status --short # one command, every lane repo
|
|
81
86
|
gr2 review create-project ~/ws default feat-x # prints gr:<sha>: one object to review
|
|
82
87
|
gr2 lane push ~/ws default feat-x # push every lane repo, each verified on its remote
|
|
83
88
|
gr2 lane show ~/ws default # where am I?
|
|
@@ -86,7 +91,7 @@ gr2 lane list ~/ws # each lane: removabl
|
|
|
86
91
|
gr2 lane remove ~/ws default feat-x # end it: its clones and record go
|
|
87
92
|
```
|
|
88
93
|
|
|
89
|
-
`lane remove` refuses while the lane is entered or leased, or was made by `lane bind`, while any of its repos holds uncommitted work, a stash, or a commit no remote has (on any branch or tag), or while its checkout holds anything that is not one of its repos; it names each one and removes nothing. `exec run` and `lane exit` require `--actor`. Every group and verb takes `--help`; `gr2 --help` lists them all.
|
|
94
|
+
`lane remove` refuses while the lane is entered or leased, or was made by `lane bind`, while any of its repos holds uncommitted work, a stash, or a commit no remote has (on any branch or tag), or while its checkout holds anything that is not one of its repos; it names each one and removes nothing. `exec run` runs whatever follows `--` in each lane repo, with your own `PATH`: a test runner works there only if it is installed where your shell finds it. `review create-project` refuses a lane repo holding any uncommitted or untracked file, so whatever a command leaves behind (`__pycache__/` after a pytest run, say) has to be in the repo's `.gitignore`. `exec run` and `lane exit` require `--actor`. Every group and verb takes `--help`; `gr2 --help` lists them all.
|
|
90
95
|
|
|
91
96
|
## What works today, and what is not there yet
|
|
92
97
|
|
|
@@ -109,17 +114,20 @@ Not there yet:
|
|
|
109
114
|
| `workspace` | init, init-from-topology, materialize, status, convert-clone, detect-gr1, migrate-gr1, retire-gr1, migrate-lane-state, bootstrap-gr1, gitinclude |
|
|
110
115
|
| `spec` | show, validate |
|
|
111
116
|
| `lane` | create, enter, exit, show, resolve, bind, lease, list, push, remove |
|
|
112
|
-
| (top level) | branch, add, commit, push, prune, status, plan, apply |
|
|
117
|
+
| (top level) | branch, add, commit, push, prune, status, plan, apply, update |
|
|
113
118
|
| `sync` | status, run |
|
|
114
119
|
| `pr` | create, status, checks, merge, view |
|
|
115
120
|
| `check` | run, show, set |
|
|
116
|
-
| `
|
|
121
|
+
| `proto` | json |
|
|
122
|
+
| `review` | open, close, checkout-pr, run, check, pin, publish, receive, verify, show, stamp, merge, update, repin, create-project, bind, approve, rebind |
|
|
117
123
|
| `exec` | status, run |
|
|
118
124
|
| `repo` | status, projection-run |
|
|
119
125
|
| `hooks` | trust, revoke, status, show, run |
|
|
120
126
|
| `store` | init, commit, check, push, status, log, diff, checkout, materialize, migrate, migrate-reviews |
|
|
121
127
|
| `target`, `config` | stored PR target; config overlays |
|
|
122
128
|
|
|
129
|
+
Every `store` verb names its workspace with `-C/--root <root>`, else reads the current directory.
|
|
130
|
+
|
|
123
131
|
`review bind`, `review approve` and `review rebind` remain as aliases of `pin`, `stamp` and `repin`.
|
|
124
132
|
|
|
125
133
|
The words these commands use (lane, pin, stamp, repin, gate, review) are defined in [docs/GLOSSARY.md](docs/GLOSSARY.md).
|
|
@@ -134,6 +142,18 @@ gr2 review stamp
|
|
|
134
142
|
gr2 review merge
|
|
135
143
|
```
|
|
136
144
|
|
|
145
|
+
A reviewer whose own workspace does not hold the reviewed repos (another team's
|
|
146
|
+
gripspace) receives the review, opens a lane, and stamps from the lane (or from one
|
|
147
|
+
repo directory in it). The stamp uses the store of the workspace the lane was opened
|
|
148
|
+
from and the repos checked out in the lane, and records the git `user.name` of that
|
|
149
|
+
workspace, not of the lane:
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
gr2 review receive <their-workspace> gr:<id> --remote <member-remote>
|
|
153
|
+
gr2 review open <their-workspace> gr:<id> --lane-dir <lane>
|
|
154
|
+
gr2 review stamp <lane>
|
|
155
|
+
```
|
|
156
|
+
|
|
137
157
|
The author recorded by the pin, and anyone who authored a commit in its range,
|
|
138
158
|
cannot stamp it. A stamp records an approval; approver names are self-declared and receipts say `signed: false`.
|
|
139
159
|
Repeated stamps by the same name count once. A moved head needs a new pin
|
|
@@ -177,6 +197,18 @@ Set it with `git config user.name 'Your Name'` there if Git has no configured na
|
|
|
177
197
|
`review show --json` and `review verify --json` include this author; older pinned reviews
|
|
178
198
|
remain readable without an author field, and reading them does not invent one.
|
|
179
199
|
|
|
200
|
+
## Run a review's tests
|
|
201
|
+
|
|
202
|
+
`gr2 review run` runs the reviewed tree's tests inside the review's lane, and only after it proves the lane equals the pinned tree. What to install and what to test comes from the reviewed repo itself: a tracked `.review-install` file at the repo root, read whenever the flags are left out. For a Python repo tested with pytest it needs two lines: the package the run must import from inside the lane, and an install that brings pytest:
|
|
203
|
+
|
|
204
|
+
```
|
|
205
|
+
# .review-install
|
|
206
|
+
package = mypkg
|
|
207
|
+
install = {venv} -m pip install -e {lane} pytest
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
`{venv}` is the lane venv's Python executable, not its directory, and `{lane}` is the lane's checkout of the repo; both are filled in per token. Without an `install` line the run uses `<lane venv python> -m pip install -e <lane>`, which installs your package and no test runner, so a pytest repo without the line refuses (`pytest_not_installed`). Either way the repo must be pip-installable (a `pyproject.toml` or `setup.py` declaring that package). For another language, declare the runner and its command instead, for example `runner = cargo` and `test = cargo test`. The recognised keys are `install`, `package`, `runner`, `test` and `reports`; any other key is refused (`bad_hint`). A repo with no `.review-install` must pass `--package` and/or `--install`, and with neither the run refuses (`no_package`). `gr2 review run --help` has the full list.
|
|
211
|
+
|
|
180
212
|
|
|
181
213
|
## Transfer a native review
|
|
182
214
|
|
|
@@ -206,6 +238,13 @@ is refused. Object downloads may remain after refusal. The owned temporary ref
|
|
|
206
238
|
is removed separately, and cleanup failure is reported without replacing a
|
|
207
239
|
primary failure.
|
|
208
240
|
|
|
241
|
+
Receive also fetches each member's pinned head from the remote it read the review
|
|
242
|
+
from, one `heads` row per member. A member whose recorded remote is another one
|
|
243
|
+
(a review published to a staging remote) is `not_this_remote`. `gr2 review open`
|
|
244
|
+
builds the lane from the range the review carries, and the row's `next` names that
|
|
245
|
+
command. `gr2 review show --diff` and `gr2 review stamp` still need the head: they
|
|
246
|
+
refuse until the author pushes it to the member's own remote and it is fetched.
|
|
247
|
+
|
|
209
248
|
The review commit carries its trees, blobs and range patches. It does not make
|
|
210
249
|
its recorded base or original member head reachable as Git parents. Keep each
|
|
211
250
|
member's base reachable at its recorded remote for reconstruction. `verify`
|
|
@@ -260,8 +299,17 @@ observation retains its fields and adds a SHA-256 `observation_id`.
|
|
|
260
299
|
A review over several members is checked as one set. `gr2 check set <workspace> <review> -- <command>`
|
|
261
300
|
reconstructs every member at its pinned head side by side (`GR2_SET_ROOT`, `GR2_REVIEW_ID` and `GR2_SET_MEMBERS`
|
|
262
301
|
name them), runs the command once, and publishes one `set` observation per member remote, carrying the review and the
|
|
263
|
-
identity of the set. `gr2 review merge`
|
|
264
|
-
|
|
302
|
+
identity of the set. With no `--check`, `gr2 review merge` on a multi-member review requires that record AND each
|
|
303
|
+
member's `test` at its head: a member whose recorded `test` is red is refused and nothing lands, and a member with no
|
|
304
|
+
`test` record of its own is decided by the passing set (members that import each other cannot pass a test alone), so
|
|
305
|
+
one `check set` and the approvals are enough to merge. `--check test` names `test` explicitly and only a `test` record
|
|
306
|
+
decides it (one that `check set --name test` wrote for this review counts); its refusal prints that `check set`. On a
|
|
307
|
+
one-member review the default `test` is also decided by a passing `set` record for this review at that head. A `set`
|
|
308
|
+
record for another review or other heads never counts. The requirement comes from the
|
|
309
|
+
review, not from the person merging: on a multi-member review `--no-set` is refused, and so is any `--check` name other
|
|
310
|
+
than `test` and `set`. `review pin` refuses a multi-member review whose rows do not each carry a `source` or a `range`,
|
|
311
|
+
because `check set` could never run on it. `check show --require set --review <id>` reads a `set` record for another
|
|
312
|
+
review as stale.
|
|
265
313
|
|
|
266
314
|
A failed command is recorded and `check run` exits 1. Publication or execution
|
|
267
315
|
refusals exit 2. `check show` returns `pass`, `fail` or `absent` in its JSON;
|