gitgrip 2.0.0a8__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.0a8 → gitgrip-2.0.0a10}/PKG-INFO +69 -12
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/README.md +67 -11
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gitgrip.egg-info/PKG-INFO +69 -12
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gitgrip.egg-info/SOURCES.txt +130 -2
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gitgrip.egg-info/requires.txt +1 -0
- gitgrip-2.0.0a10/gr2/PLATFORM_ADAPTER_CHANGELOG.md +113 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/prototypes/lane_workspace_prototype.py +25 -3
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/prototypes/repo_maintenance_prototype.py +60 -22
- 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.0a10/gr2/python_cli/agent_record.py +269 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/app.py +1239 -140
- gitgrip-2.0.0a10/gr2/python_cli/approvals.py +529 -0
- 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.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/clone_exec.py +75 -1
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/consent.py +83 -47
- gitgrip-2.0.0a10/gr2/python_cli/declared_sets.py +217 -0
- {gitgrip-2.0.0a8 → 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.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/execops.py +20 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/git_review.py +2 -1
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/gitops.py +59 -4
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/grip.py +489 -30
- gitgrip-2.0.0a10/gr2/python_cli/grip_cli.py +4112 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/hooks.py +289 -1
- {gitgrip-2.0.0a8 → 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.0a10/gr2/python_cli/member_field_tree.py +202 -0
- gitgrip-2.0.0a10/gr2/python_cli/merge_gate.py +662 -0
- gitgrip-2.0.0a10/gr2/python_cli/merge_receipts.py +67 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/migration.py +170 -38
- gitgrip-2.0.0a10/gr2/python_cli/names.py +78 -0
- gitgrip-2.0.0a10/gr2/python_cli/next_steps.py +215 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/open_gr_review.py +58 -22
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/platform.py +118 -5
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/pr.py +58 -4
- gitgrip-2.0.0a10/gr2/python_cli/proto_json.py +122 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/push.py +113 -2
- {gitgrip-2.0.0a8 → 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.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/review_ephemeral.py +34 -6
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/review_field_tree.py +141 -32
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/review_members.py +11 -3
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/review_rebind.py +12 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/review_run.py +56 -2
- gitgrip-2.0.0a10/gr2/python_cli/review_update.py +176 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/root_option.py +35 -0
- gitgrip-2.0.0a10/gr2/python_cli/set_check.py +353 -0
- gitgrip-2.0.0a10/gr2/python_cli/set_hints.py +132 -0
- gitgrip-2.0.0a10/gr2/python_cli/shadow.py +190 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/spec_apply.py +83 -8
- gitgrip-2.0.0a10/gr2/python_cli/store_hooks.py +596 -0
- {gitgrip-2.0.0a8 → 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.0a8 → 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.0a10/gr2/python_cli/workspace_mode.py +50 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/schemas/dev.synapt.grip.review.v1alpha1/descriptor_set.pb +4 -3
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/schemas/dev.synapt.grip.review.v1alpha1/review.proto +1 -0
- {gitgrip-2.0.0a8 → 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_agent_record_append.py +360 -0
- gitgrip-2.0.0a10/tests/test_agent_record_fold.py +334 -0
- gitgrip-2.0.0a10/tests/test_agent_record_stamps.py +210 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_api_dump.py +4 -1
- 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.0a8 → gitgrip-2.0.0a10}/tests/test_break_18_gr1_sibling_units.py +45 -30
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_clone_materialization.py +130 -0
- gitgrip-2.0.0a10/tests/test_consent_key_paths.py +215 -0
- gitgrip-2.0.0a10/tests/test_declared_set_pins.py +144 -0
- gitgrip-2.0.0a10/tests/test_declared_sets.py +416 -0
- {gitgrip-2.0.0a8 → 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.0a8 → gitgrip-2.0.0a10}/tests/test_event_outcome_policy.py +2 -1
- gitgrip-2.0.0a10/tests/test_exec_run_names_what_did_not_run.py +95 -0
- 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_field_tree_schema_reader.py +140 -0
- gitgrip-2.0.0a10/tests/test_files_compose.py +382 -0
- gitgrip-2.0.0a10/tests/test_git_transport_allow_list.py +254 -0
- gitgrip-2.0.0a10/tests/test_gitops_locating_env.py +109 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_gitops_shared.py +15 -5
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_gr_installed_wheel.py +9 -3
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_gr_shadow.py +27 -0
- gitgrip-2.0.0a10/tests/test_grip_toml_literals.py +95 -0
- gitgrip-2.0.0a10/tests/test_hostile_names.py +218 -0
- gitgrip-2.0.0a10/tests/test_hostile_names_helper.py +83 -0
- 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.0a8 → gitgrip-2.0.0a10}/tests/test_lane_create_defaults.py +104 -5
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_lane_exit_keeps_dirty_work.py +53 -0
- gitgrip-2.0.0a10/tests/test_lane_push.py +291 -0
- gitgrip-2.0.0a10/tests/test_lane_remove.py +460 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_lane_store_path_pins.py +16 -14
- {gitgrip-2.0.0a8 → 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_malformed_remote_refusal.py +46 -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.0a8 → gitgrip-2.0.0a10}/tests/test_migration.py +3 -1
- gitgrip-2.0.0a10/tests/test_names.py +50 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_native_store_gitinclude.py +1 -1
- gitgrip-2.0.0a10/tests/test_np_bench_contract_scenario.py +131 -0
- gitgrip-2.0.0a10/tests/test_one_pin_record.py +399 -0
- gitgrip-2.0.0a10/tests/test_out_of_set_hint.py +181 -0
- gitgrip-2.0.0a10/tests/test_outside_names_as_git_options.py +272 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_platform_adapter_plugins.py +2 -0
- gitgrip-2.0.0a10/tests/test_pr_adapter_v2_target.py +377 -0
- gitgrip-2.0.0a10/tests/test_pr_create_pins_itself.py +279 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_pr_review_subject.py +30 -0
- gitgrip-2.0.0a10/tests/test_proto_json.py +145 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_push.py +1 -1
- gitgrip-2.0.0a10/tests/test_readme_walk.py +169 -0
- {gitgrip-2.0.0a8 → 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.0a10/tests/test_retire_gr1.py +137 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_a4_v2.py +57 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_a4_v3.py +17 -5
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_approvals.py +299 -13
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_bind_author.py +16 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_bind_verify.py +8 -5
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_cli.py +5 -4
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_close_keeps_local_work.py +224 -2
- {gitgrip-2.0.0a8 → 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.0a8 → gitgrip-2.0.0a10}/tests/test_review_merge_gate.py +136 -6
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_merge_gate_lost_ack.py +14 -10
- gitgrip-2.0.0a10/tests/test_review_merge_platform.py +344 -0
- gitgrip-2.0.0a10/tests/test_review_merge_receipt.py +136 -0
- 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.0a10/tests/test_review_merge_updates_tracking_ref.py +154 -0
- gitgrip-2.0.0a10/tests/test_review_named_refusals.py +53 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_open_lane.py +321 -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.0a8 → 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_run_deleted_cwd.py +73 -0
- gitgrip-2.0.0a10/tests/test_review_run_package_name.py +40 -0
- gitgrip-2.0.0a10/tests/test_review_run_venv_and_refusal_identity.py +133 -0
- gitgrip-2.0.0a10/tests/test_review_show_diff.py +464 -0
- {gitgrip-2.0.0a8 → 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.0a8 → gitgrip-2.0.0a10}/tests/test_root_option_verbs.py +12 -6
- gitgrip-2.0.0a10/tests/test_set_check.py +366 -0
- 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.0a10/tests/test_set_check_remote_heads.py +164 -0
- gitgrip-2.0.0a10/tests/test_shadow.py +163 -0
- gitgrip-2.0.0a10/tests/test_shadow_lease.py +178 -0
- gitgrip-2.0.0a10/tests/test_skill_dump.py +112 -0
- gitgrip-2.0.0a10/tests/test_spec_show_native_root.py +140 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_store_break_attempts.py +11 -3
- 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_commit_follows_branch.py +158 -0
- gitgrip-2.0.0a10/tests/test_store_commit_keeps_record.py +152 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_store_commit_noop.py +4 -4
- gitgrip-2.0.0a10/tests/test_store_commit_refuses_rewind.py +499 -0
- gitgrip-2.0.0a10/tests/test_store_fence_no_pin.py +61 -0
- gitgrip-2.0.0a10/tests/test_store_full_mode_carrier.py +367 -0
- gitgrip-2.0.0a10/tests/test_store_full_mode_coverage.py +386 -0
- gitgrip-2.0.0a10/tests/test_store_full_mode_layers.py +457 -0
- gitgrip-2.0.0a10/tests/test_store_full_mode_records.py +244 -0
- gitgrip-2.0.0a10/tests/test_store_git_hooks.py +641 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_store_git_native_smoke.py +1 -0
- gitgrip-2.0.0a10/tests/test_store_gitmodules.py +188 -0
- gitgrip-2.0.0a10/tests/test_store_gitmodules_branch.py +150 -0
- gitgrip-2.0.0a10/tests/test_store_hook_takes_verb_coverage.py +190 -0
- gitgrip-2.0.0a10/tests/test_store_init_clone.py +220 -0
- 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.0a10/tests/test_store_materialize_branch.py +174 -0
- gitgrip-2.0.0a10/tests/test_store_materialize_fetches_new_pin.py +214 -0
- gitgrip-2.0.0a10/tests/test_store_materialize_installs_hooks.py +179 -0
- {gitgrip-2.0.0a8 → 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_inspection.py +129 -0
- gitgrip-2.0.0a10/tests/test_store_status_push_undeclared_gitlink.py +92 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_store_status_values.py +49 -0
- gitgrip-2.0.0a10/tests/test_store_submodule_init.py +146 -0
- gitgrip-2.0.0a10/tests/test_store_submodule_update_merge.py +172 -0
- gitgrip-2.0.0a10/tests/test_store_untracked_member.py +99 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_store_verb_witnesses.py +212 -7
- 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.0a8 → gitgrip-2.0.0a10}/tests/test_version_identity.py +35 -3
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_version_static.py +8 -4
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_workspace_convert_clone.py +196 -0
- {gitgrip-2.0.0a8 → 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.0a8/gr2/PLATFORM_ADAPTER_CHANGELOG.md +0 -67
- gitgrip-2.0.0a8/gr2/python_cli/add.py +0 -51
- gitgrip-2.0.0a8/gr2/python_cli/approvals.py +0 -302
- gitgrip-2.0.0a8/gr2/python_cli/grip_cli.py +0 -2137
- gitgrip-2.0.0a8/gr2/python_cli/merge_gate.py +0 -286
- gitgrip-2.0.0a8/gr2/python_cli/workspace_guidance.py +0 -22
- gitgrip-2.0.0a8/tests/test_add.py +0 -129
- gitgrip-2.0.0a8/tests/test_migration_unadopted_notice.py +0 -124
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gitgrip.egg-info/dependency_links.txt +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gitgrip.egg-info/entry_points.txt +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gitgrip.egg-info/top_level.txt +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/__init__.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/api_core.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/overlay/__init__.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/overlay/activate.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/overlay/agent_manifest.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/overlay/cli.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/overlay/cross_repo.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/overlay/drivers.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/overlay/introspection.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/overlay/language_drivers.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/overlay/objects.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/overlay/perf.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/overlay/refs.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/overlay/trust.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/overlay/types.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/overlay/units.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/overlay/workspace_spec.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/prototypes/__init__.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/prototypes/cache_materialization_probe.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/prototypes/concurrent_event_stress.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/prototypes/concurrent_lease_stress.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/prototypes/concurrent_workspace_cap_stress.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/prototypes/contribution_protocol.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/prototypes/cross_mode_lane_stress.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/prototypes/jsonl_store.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/prototypes/layout_model_probe.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/prototypes/propagation_daemon.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/prototypes/propagation_state_machine.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/prototypes/python_exec_playground.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/prototypes/python_hook_runtime_playground.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/prototypes/python_migration_playground.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/prototypes/python_review_checkout_playground.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/prototypes/python_spec_apply_playground.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/prototypes/real_git_lane_materialization.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/prototypes/real_git_playground.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/prototypes/recall_lane_history.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/prototypes/repo_transport_probe.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/__init__.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/__main__.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/approval_schema.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/branch.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/channel_bridge.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/check_records.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/commit.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/config.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/context.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/ecosystems_python.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/env_exec.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/events.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/exit_codes.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/failures.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/file_exec.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/gitinclude.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/gr_resolver.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/gr_shadow.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/lane_defaults.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/lane_graph.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/lane_plugins.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/launch_exec.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/layout.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/merge_verification.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/project_review.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/prune.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/review_allocation.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/review_dispatch.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/review_records.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/review_runners.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/staging_cleanup.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/target.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/python_cli/workspace_snapshot.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/schemas/dev.synapt.grip.approval.v1alpha1/approval.proto +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/schemas/dev.synapt.grip.approval.v1alpha1/descriptor_set.pb +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/schemas/dev.synapt.grip.check.v1alpha1/check.proto +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/schemas/dev.synapt.grip.check.v1alpha1/descriptor_set.pb +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/schemas/dev.synapt.grip.merge.v1alpha1/descriptor_set.pb +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/schemas/dev.synapt.grip.merge.v1alpha1/merge.proto +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/schemas/gr2-materialization-plan-v1.schema.json +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2/schemas/gr2-workspace-spec-v1.schema.json +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/gr2_overlay/__init__.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/setup.cfg +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_agent_manifest_overlay_source.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_api_core_seam.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_app_event_outcomes.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_apply_convergence.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_apply_gr1_sibling_adoption.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_approval_schema.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_branch.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_break_17_unit_path_containment.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_channel_bridge.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_cli_adapter_error_boundary.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_cli_shape_witnesses.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_commit.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_config_base_path_guard.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_config_overlay.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_conftest_git_isolation.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_context_resolver.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_contribution_protocol.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_deprecation_registry.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_ecosystems_python.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_ensure_lane_checkout_reference_clone.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_env_materialization.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_event_log_integrity.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_events.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_events_torn_line.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_exec_apostrophe_and_oserror.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_exec_single_string_and_materialize_plan.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_execops.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_failure_event_outcome.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_field_tree_name.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_first_five_minutes.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_foreground_launch_runtime.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_git_review.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_gitinclude_compiler.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_gr1_first_run_guidance.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_gr2_packaging.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_gr2_review_receipt.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_gr_resolved_cleared.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_gr_resolver_conformance.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_grip_cli.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_grip_hardening.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_grip_snapshot.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_grip_toml_schema_v1.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_hook_events.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_hook_hardening.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_hooks_consent.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_hooks_group_names.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_jsonl_store.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_lane_checkout_root.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_lane_create_fork_base_cli.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_lane_create_refusal_leaves_nothing.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_lane_create_refuses_own_branch.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_lane_downstream.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_lane_downstream_run.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_lane_enter_hook_warnings.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_lane_graph.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_lane_lease_show_json.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_lane_lifecycle_safety.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_lane_plugins.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_lane_probe.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_lane_probe_batch.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_lane_repo_paths_and_all_skipped.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_lane_roles.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_lane_show_name.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_lane_toml_serialization.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_launch_primitive.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_linked_review_receipts.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_m2_overlay_hindsight.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_m2_overlay_mem0.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_m2_overlay_zep.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_materialization_plan_contract.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_materialize_pin.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_member_working_root_checkout_materialize.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_merge_evidence.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_merge_parent_verification.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_migration_overlay_compatibility.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_native_store_review_record_probes.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_no_bare_python_cli_imports.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_null_current_lane_refusal.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_open_gr_enter.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_open_project_refusal_reason_cli.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_outbox_ack_after_effect.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_overlay_acceptance.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_overlay_activate.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_overlay_cli.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_overlay_cli_wiring.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_overlay_composition_merge.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_overlay_cross_repo_atomic_apply.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_overlay_cross_repo_perf_gate.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_overlay_cross_repo_rollback.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_overlay_driver_registry.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_overlay_introspection.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_overlay_multi_stack.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_overlay_object_encoding.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_overlay_perf_gates.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_overlay_python_driver.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_overlay_tier_b_encoding.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_overlay_tier_b_perf_gates.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_overlay_tier_b_repo_state.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_overlay_tier_b_staging_discipline.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_overlay_trust_model.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_overlay_workspace_spec.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_platform_adapter_changelog.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_pr_events.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_pr_group_legibility.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_pr_merge_head_pin.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_pr_merge_method.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_pr_merge_missing_target.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_pr_merge_partial_failure.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_pr_view.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_project_file_materialization.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_project_review_range_reconstruction.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_project_review_three_repo.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_projection_tracked_dest.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_propagation_contribution.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_propagation_daemon.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_propagation_state_machine.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_prune.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_python_group_install.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_readme_verbs_exist.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_remote_check_records.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_repo_path_read_through.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_repo_status_linked_worktree.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_repo_status_schema_version.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_repo_status_symlinked_git_dir.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_a4.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_allocation_recovery.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_ansi_parse.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_b3_reader_alignment.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_bind_fork_base.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_bind_from_range.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_bind_migration.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_bind_native_store.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_bind_root_refs.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_check_name.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_close_gr.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_context_defaults.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_context_witnesses.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_create_project_cli.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_dispatch.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_ephemeral.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_events.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_field_tree_reader_edges.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_field_tree_readers.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_install_hint.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_pin_stamp_names.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_pr_marker_context.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_rebind.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_receipt_cleanup.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_ref_v1_migration.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_ref_v1_reader.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_ref_v1_writer.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_remote_safety.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_run.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_run_context.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_run_dependency_order.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_run_import_isolation.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_run_integrity_recheck.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_run_multi_repo.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_run_plugin_order.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_run_rerun_and_refusal_receipt.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_runners.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_subject.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_v1_format_guard.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_verify_inside.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_review_vocabulary.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_rmtree_or_refuse.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_selected_workspace_commit.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_single_repo_cwd_refusal.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_snapshot_id_prefix_resolution.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_spec_apply_event_outcomes.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_spec_declaration_ref_pin.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_sprint21_sync_platform.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_staging_cleanup.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_store_checkout_atomicity.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_store_declared_members.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_store_init_branch_inference.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_store_log_adoption_boundary.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_store_member_path_hygiene.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_store_migrate_branch_inference.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_store_moved_workspace_guard.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_store_verb_rename.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_submodule_member_predicate.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_superproject_import.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_sync_event_outcomes.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_sync_fast_forward.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_sync_fetch.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_sync_seed_local.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_sync_ssh_rewrite.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_sync_status_probe.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_target.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_tmux_launch_runtime.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_unit_abort.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_unit_apply.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_unit_apply_dry_run.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_unit_manifest_schema.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_unit_propose.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_unit_topological_apply.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_validate_repo_path_conflict.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_vocabulary.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_workspace_edit_lease_cap.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_workspace_init_from_topology.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_workspace_init_local_repos.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_workspace_root_defaults.py +0 -0
- {gitgrip-2.0.0a8 → gitgrip-2.0.0a10}/tests/test_workspace_root_nearest_marker.py +0 -0
- {gitgrip-2.0.0a8 → 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,30 +64,34 @@ 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
|
|
87
|
+
gr2 lane push ~/ws default feat-x # push every lane repo, each verified on its remote
|
|
82
88
|
gr2 lane show ~/ws default # where am I?
|
|
83
89
|
gr2 lane exit ~/ws default --actor human:you
|
|
90
|
+
gr2 lane list ~/ws # each lane: removable, or keep and why
|
|
91
|
+
gr2 lane remove ~/ws default feat-x # end it: its clones and record go
|
|
84
92
|
```
|
|
85
93
|
|
|
86
|
-
`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.
|
|
87
95
|
|
|
88
96
|
## What works today, and what is not there yet
|
|
89
97
|
|
|
@@ -103,20 +111,23 @@ Not there yet:
|
|
|
103
111
|
|
|
104
112
|
| Group | Verbs |
|
|
105
113
|
|---|---|
|
|
106
|
-
| `workspace` | init, init-from-topology, materialize, status, convert-clone, detect-gr1, migrate-gr1, migrate-lane-state, bootstrap-gr1, gitinclude |
|
|
114
|
+
| `workspace` | init, init-from-topology, materialize, status, convert-clone, detect-gr1, migrate-gr1, retire-gr1, migrate-lane-state, bootstrap-gr1, gitinclude |
|
|
107
115
|
| `spec` | show, validate |
|
|
108
|
-
| `lane` | create, enter, exit, show, resolve, bind, lease |
|
|
109
|
-
| (top level) | branch, add, commit, push, prune, status, plan, apply |
|
|
116
|
+
| `lane` | create, enter, exit, show, resolve, bind, lease, list, push, remove |
|
|
117
|
+
| (top level) | branch, add, commit, push, prune, status, plan, apply, update |
|
|
110
118
|
| `sync` | status, run |
|
|
111
119
|
| `pr` | create, status, checks, merge, view |
|
|
112
|
-
| `check` | run, show |
|
|
113
|
-
| `
|
|
120
|
+
| `check` | run, show, set |
|
|
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 |
|
|
114
123
|
| `exec` | status, run |
|
|
115
124
|
| `repo` | status, projection-run |
|
|
116
125
|
| `hooks` | trust, revoke, status, show, run |
|
|
117
126
|
| `store` | init, commit, check, push, status, log, diff, checkout, materialize, migrate, migrate-reviews |
|
|
118
127
|
| `target`, `config` | stored PR target; config overlays |
|
|
119
128
|
|
|
129
|
+
Every `store` verb names its workspace with `-C/--root <root>`, else reads the current directory.
|
|
130
|
+
|
|
120
131
|
`review bind`, `review approve` and `review rebind` remain as aliases of `pin`, `stamp` and `repin`.
|
|
121
132
|
|
|
122
133
|
The words these commands use (lane, pin, stamp, repin, gate, review) are defined in [docs/GLOSSARY.md](docs/GLOSSARY.md).
|
|
@@ -131,6 +142,18 @@ gr2 review stamp
|
|
|
131
142
|
gr2 review merge
|
|
132
143
|
```
|
|
133
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
|
+
|
|
134
157
|
The author recorded by the pin, and anyone who authored a commit in its range,
|
|
135
158
|
cannot stamp it. A stamp records an approval; approver names are self-declared and receipts say `signed: false`.
|
|
136
159
|
Repeated stamps by the same name count once. A moved head needs a new pin
|
|
@@ -174,6 +197,18 @@ Set it with `git config user.name 'Your Name'` there if Git has no configured na
|
|
|
174
197
|
`review show --json` and `review verify --json` include this author; older pinned reviews
|
|
175
198
|
remain readable without an author field, and reading them does not invent one.
|
|
176
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
|
+
|
|
177
212
|
|
|
178
213
|
## Transfer a native review
|
|
179
214
|
|
|
@@ -203,6 +238,13 @@ is refused. Object downloads may remain after refusal. The owned temporary ref
|
|
|
203
238
|
is removed separately, and cleanup failure is reported without replacing a
|
|
204
239
|
primary failure.
|
|
205
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
|
+
|
|
206
248
|
The review commit carries its trees, blobs and range patches. It does not make
|
|
207
249
|
its recorded base or original member head reachable as Git parents. Keep each
|
|
208
250
|
member's base reachable at its recorded remote for reconstruction. `verify`
|
|
@@ -254,6 +296,21 @@ The read JSON contains `status`, `record_id` (the head's record-set blob id or
|
|
|
254
296
|
null), `snapshot_oid`, `head`, `member_key`, `records`, and `reason`. Each
|
|
255
297
|
observation retains its fields and adds a SHA-256 `observation_id`.
|
|
256
298
|
|
|
299
|
+
A review over several members is checked as one set. `gr2 check set <workspace> <review> -- <command>`
|
|
300
|
+
reconstructs every member at its pinned head side by side (`GR2_SET_ROOT`, `GR2_REVIEW_ID` and `GR2_SET_MEMBERS`
|
|
301
|
+
name them), runs the command once, and publishes one `set` observation per member remote, carrying the review and the
|
|
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.
|
|
313
|
+
|
|
257
314
|
A failed command is recorded and `check run` exits 1. Publication or execution
|
|
258
315
|
refusals exit 2. `check show` returns `pass`, `fail` or `absent` in its JSON;
|
|
259
316
|
failed or unmeasurable reads exit 2. Conflicting pass and fail observations both
|
|
@@ -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,30 +47,34 @@ 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
|
|
70
|
+
gr2 lane push ~/ws default feat-x # push every lane repo, each verified on its remote
|
|
66
71
|
gr2 lane show ~/ws default # where am I?
|
|
67
72
|
gr2 lane exit ~/ws default --actor human:you
|
|
73
|
+
gr2 lane list ~/ws # each lane: removable, or keep and why
|
|
74
|
+
gr2 lane remove ~/ws default feat-x # end it: its clones and record go
|
|
68
75
|
```
|
|
69
76
|
|
|
70
|
-
`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.
|
|
71
78
|
|
|
72
79
|
## What works today, and what is not there yet
|
|
73
80
|
|
|
@@ -87,20 +94,23 @@ Not there yet:
|
|
|
87
94
|
|
|
88
95
|
| Group | Verbs |
|
|
89
96
|
|---|---|
|
|
90
|
-
| `workspace` | init, init-from-topology, materialize, status, convert-clone, detect-gr1, migrate-gr1, migrate-lane-state, bootstrap-gr1, gitinclude |
|
|
97
|
+
| `workspace` | init, init-from-topology, materialize, status, convert-clone, detect-gr1, migrate-gr1, retire-gr1, migrate-lane-state, bootstrap-gr1, gitinclude |
|
|
91
98
|
| `spec` | show, validate |
|
|
92
|
-
| `lane` | create, enter, exit, show, resolve, bind, lease |
|
|
93
|
-
| (top level) | branch, add, commit, push, prune, status, plan, apply |
|
|
99
|
+
| `lane` | create, enter, exit, show, resolve, bind, lease, list, push, remove |
|
|
100
|
+
| (top level) | branch, add, commit, push, prune, status, plan, apply, update |
|
|
94
101
|
| `sync` | status, run |
|
|
95
102
|
| `pr` | create, status, checks, merge, view |
|
|
96
|
-
| `check` | run, show |
|
|
97
|
-
| `
|
|
103
|
+
| `check` | run, show, set |
|
|
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 |
|
|
98
106
|
| `exec` | status, run |
|
|
99
107
|
| `repo` | status, projection-run |
|
|
100
108
|
| `hooks` | trust, revoke, status, show, run |
|
|
101
109
|
| `store` | init, commit, check, push, status, log, diff, checkout, materialize, migrate, migrate-reviews |
|
|
102
110
|
| `target`, `config` | stored PR target; config overlays |
|
|
103
111
|
|
|
112
|
+
Every `store` verb names its workspace with `-C/--root <root>`, else reads the current directory.
|
|
113
|
+
|
|
104
114
|
`review bind`, `review approve` and `review rebind` remain as aliases of `pin`, `stamp` and `repin`.
|
|
105
115
|
|
|
106
116
|
The words these commands use (lane, pin, stamp, repin, gate, review) are defined in [docs/GLOSSARY.md](docs/GLOSSARY.md).
|
|
@@ -115,6 +125,18 @@ gr2 review stamp
|
|
|
115
125
|
gr2 review merge
|
|
116
126
|
```
|
|
117
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
|
+
|
|
118
140
|
The author recorded by the pin, and anyone who authored a commit in its range,
|
|
119
141
|
cannot stamp it. A stamp records an approval; approver names are self-declared and receipts say `signed: false`.
|
|
120
142
|
Repeated stamps by the same name count once. A moved head needs a new pin
|
|
@@ -158,6 +180,18 @@ Set it with `git config user.name 'Your Name'` there if Git has no configured na
|
|
|
158
180
|
`review show --json` and `review verify --json` include this author; older pinned reviews
|
|
159
181
|
remain readable without an author field, and reading them does not invent one.
|
|
160
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
|
+
|
|
161
195
|
|
|
162
196
|
## Transfer a native review
|
|
163
197
|
|
|
@@ -187,6 +221,13 @@ is refused. Object downloads may remain after refusal. The owned temporary ref
|
|
|
187
221
|
is removed separately, and cleanup failure is reported without replacing a
|
|
188
222
|
primary failure.
|
|
189
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
|
+
|
|
190
231
|
The review commit carries its trees, blobs and range patches. It does not make
|
|
191
232
|
its recorded base or original member head reachable as Git parents. Keep each
|
|
192
233
|
member's base reachable at its recorded remote for reconstruction. `verify`
|
|
@@ -238,6 +279,21 @@ The read JSON contains `status`, `record_id` (the head's record-set blob id or
|
|
|
238
279
|
null), `snapshot_oid`, `head`, `member_key`, `records`, and `reason`. Each
|
|
239
280
|
observation retains its fields and adds a SHA-256 `observation_id`.
|
|
240
281
|
|
|
282
|
+
A review over several members is checked as one set. `gr2 check set <workspace> <review> -- <command>`
|
|
283
|
+
reconstructs every member at its pinned head side by side (`GR2_SET_ROOT`, `GR2_REVIEW_ID` and `GR2_SET_MEMBERS`
|
|
284
|
+
name them), runs the command once, and publishes one `set` observation per member remote, carrying the review and the
|
|
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.
|
|
296
|
+
|
|
241
297
|
A failed command is recorded and `check run` exits 1. Publication or execution
|
|
242
298
|
refusals exit 2. `check show` returns `pass`, `fail` or `absent` in its JSON;
|
|
243
299
|
failed or unmeasurable reads exit 2. Conflicting pass and fail observations both
|
|
@@ -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,30 +64,34 @@ 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
|
|
87
|
+
gr2 lane push ~/ws default feat-x # push every lane repo, each verified on its remote
|
|
82
88
|
gr2 lane show ~/ws default # where am I?
|
|
83
89
|
gr2 lane exit ~/ws default --actor human:you
|
|
90
|
+
gr2 lane list ~/ws # each lane: removable, or keep and why
|
|
91
|
+
gr2 lane remove ~/ws default feat-x # end it: its clones and record go
|
|
84
92
|
```
|
|
85
93
|
|
|
86
|
-
`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.
|
|
87
95
|
|
|
88
96
|
## What works today, and what is not there yet
|
|
89
97
|
|
|
@@ -103,20 +111,23 @@ Not there yet:
|
|
|
103
111
|
|
|
104
112
|
| Group | Verbs |
|
|
105
113
|
|---|---|
|
|
106
|
-
| `workspace` | init, init-from-topology, materialize, status, convert-clone, detect-gr1, migrate-gr1, migrate-lane-state, bootstrap-gr1, gitinclude |
|
|
114
|
+
| `workspace` | init, init-from-topology, materialize, status, convert-clone, detect-gr1, migrate-gr1, retire-gr1, migrate-lane-state, bootstrap-gr1, gitinclude |
|
|
107
115
|
| `spec` | show, validate |
|
|
108
|
-
| `lane` | create, enter, exit, show, resolve, bind, lease |
|
|
109
|
-
| (top level) | branch, add, commit, push, prune, status, plan, apply |
|
|
116
|
+
| `lane` | create, enter, exit, show, resolve, bind, lease, list, push, remove |
|
|
117
|
+
| (top level) | branch, add, commit, push, prune, status, plan, apply, update |
|
|
110
118
|
| `sync` | status, run |
|
|
111
119
|
| `pr` | create, status, checks, merge, view |
|
|
112
|
-
| `check` | run, show |
|
|
113
|
-
| `
|
|
120
|
+
| `check` | run, show, set |
|
|
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 |
|
|
114
123
|
| `exec` | status, run |
|
|
115
124
|
| `repo` | status, projection-run |
|
|
116
125
|
| `hooks` | trust, revoke, status, show, run |
|
|
117
126
|
| `store` | init, commit, check, push, status, log, diff, checkout, materialize, migrate, migrate-reviews |
|
|
118
127
|
| `target`, `config` | stored PR target; config overlays |
|
|
119
128
|
|
|
129
|
+
Every `store` verb names its workspace with `-C/--root <root>`, else reads the current directory.
|
|
130
|
+
|
|
120
131
|
`review bind`, `review approve` and `review rebind` remain as aliases of `pin`, `stamp` and `repin`.
|
|
121
132
|
|
|
122
133
|
The words these commands use (lane, pin, stamp, repin, gate, review) are defined in [docs/GLOSSARY.md](docs/GLOSSARY.md).
|
|
@@ -131,6 +142,18 @@ gr2 review stamp
|
|
|
131
142
|
gr2 review merge
|
|
132
143
|
```
|
|
133
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
|
+
|
|
134
157
|
The author recorded by the pin, and anyone who authored a commit in its range,
|
|
135
158
|
cannot stamp it. A stamp records an approval; approver names are self-declared and receipts say `signed: false`.
|
|
136
159
|
Repeated stamps by the same name count once. A moved head needs a new pin
|
|
@@ -174,6 +197,18 @@ Set it with `git config user.name 'Your Name'` there if Git has no configured na
|
|
|
174
197
|
`review show --json` and `review verify --json` include this author; older pinned reviews
|
|
175
198
|
remain readable without an author field, and reading them does not invent one.
|
|
176
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
|
+
|
|
177
212
|
|
|
178
213
|
## Transfer a native review
|
|
179
214
|
|
|
@@ -203,6 +238,13 @@ is refused. Object downloads may remain after refusal. The owned temporary ref
|
|
|
203
238
|
is removed separately, and cleanup failure is reported without replacing a
|
|
204
239
|
primary failure.
|
|
205
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
|
+
|
|
206
248
|
The review commit carries its trees, blobs and range patches. It does not make
|
|
207
249
|
its recorded base or original member head reachable as Git parents. Keep each
|
|
208
250
|
member's base reachable at its recorded remote for reconstruction. `verify`
|
|
@@ -254,6 +296,21 @@ The read JSON contains `status`, `record_id` (the head's record-set blob id or
|
|
|
254
296
|
null), `snapshot_oid`, `head`, `member_key`, `records`, and `reason`. Each
|
|
255
297
|
observation retains its fields and adds a SHA-256 `observation_id`.
|
|
256
298
|
|
|
299
|
+
A review over several members is checked as one set. `gr2 check set <workspace> <review> -- <command>`
|
|
300
|
+
reconstructs every member at its pinned head side by side (`GR2_SET_ROOT`, `GR2_REVIEW_ID` and `GR2_SET_MEMBERS`
|
|
301
|
+
name them), runs the command once, and publishes one `set` observation per member remote, carrying the review and the
|
|
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.
|
|
313
|
+
|
|
257
314
|
A failed command is recorded and `check run` exits 1. Publication or execution
|
|
258
315
|
refusals exit 2. `check show` returns `pass`, `fail` or `absent` in its JSON;
|
|
259
316
|
failed or unmeasurable reads exit 2. Conflicting pass and fail observations both
|