feat BREAKING PMHF-b feat/post-merge-handover-freshness #2 / 3
aaronrene · 34 days ago · Jul 31, 2026 · Diff

feat(PMHF-b): post-merge handover freshness land closeout (BV pass PMHF-BV-r1)

Built exactly to frozen docs/PHASE-PMHF-POST-MERGE-HANDOVER-FRESHNESS.md (PMHF-r4): - tools/land_closeout/ (LandCloseoutReport + check_land_closeout, PMHF.5 resolution order) - ok land-closeout (exit 0/2; probe default on for git regimes, off muse-only) - ok status --exit-code folds land_closeout.ok into exit 2 (land_a_in_progress stays ok) - land-check refuses non-complete closeout (PMHF.6.5 tokens) - next_regen land-phase= marker + land-b emission (frozen PMHF.3.2 paste; dry-run body) - templates/ci/governance-closeout-github-actions.yml (comment-only; never writes main) - handover template rule 8 + governance-sync skill + tier-authority touchpoints; SPEC 5 rows - seven-tier PMHF.10 tests: 46 green; BV re-run evidence sha256:929fb54d...

ROADMAP PMHF-b -> DONE; queue adds PMHF -> main. HANDOVER NEXT -> PMHF -> main (land-a), marker land-phase=land-a. No main merge this session.

sha256:72efabb7bebf54347c1e4ac4368f3c01c89074a555c4eb0fcfbe9680c3d457c3 sha
+284 ~35 −9 symbols
sha256:18992c060b455c0d6cfc4a0b2e9eca9793b62a9244a901b9f298836c9a61bbf6 snapshot
+284
symbols added
~35
symbols modified
−9
symbols removed
0
dead code introduced
Semantic Changes 328 symbols
~ cli/commands/land_closeout.py .py 12 symbols added
+ CliContext import import CliContext L9–9
+ ConfigError import import ConfigError L8–8
+ Namespace import import Namespace L5–5
+ annotations import import annotations L3–3
+ check_land_closeout import import check_land_closeout L12–12
+ format_config_error import import format_config_error L11–11
+ is_within_repo import import is_within_repo L10–10
+ land_closeout_payload import import land_closeout_payload L12–12
+ load_config import import load_config L7–7
+ resolve_config_path import import resolve_config_path L10–10
+ resolve_repo_root import import resolve_repo_root L10–10
+ run_land_closeout_command function function run_land_closeout_command L15–50
+ CI_TEMPLATE variable variable CI_TEMPLATE L19–19
+ _doc_bytes function function _doc_bytes L22–24
+ KIT_ROOT import import KIT_ROOT L10–10
+ Path import import Path L7–7
+ annotations import import annotations L4–4
+ git_status_runner import import git_status_runner L10–10
+ json import import json L6–6
+ kit_root import import kit_root L9–9
+ make_runner import import make_runner L10–10
+ ok import import ok L10–10
+ run_cli import import run_cli L10–10
+ seed_land_repo import import seed_land_repo L10–10
+ test_ci_template_has_no_apply_to_main_step function function test_ci_template_has_no_apply_to_main_step L72–83
+ test_dry_run_governance_sync_still_only_stamps_marker function function test_dry_run_governance_sync_still_only_stamps_marker L86–106
+ test_land_closeout_idempotent function function test_land_closeout_idempotent L56–69
+ test_status_and_land_closeout_never_write_docs function function test_status_and_land_closeout_never_write_docs L27–53
~ tests/e2e/test_land_closeout_cycle.py .py 15 symbols added
+ _runner function function _runner L20–38
+ _status function function _status L41–49
+ Path import import Path L14–14
+ annotations import import annotations L8–8
+ date import import date L13–13
+ io import import io L10–10
+ json import import json L11–11
+ kit_root import import kit_root L16–16
+ make_runner import import make_runner L17–17
+ ok import import ok L17–17
+ redirect_stdout import import redirect_stdout L12–12
+ run_cli import import run_cli L17–17
+ seed_land_repo import import seed_land_repo L17–17
+ test_land_cycle_status_gate_land_b_then_complete function function test_land_cycle_status_gate_land_b_then_complete L52–111
+ test_re_pasting_land_a_after_merge_stays_fail_closed function function test_re_pasting_land_a_after_merge_stays_fail_closed L114–123
+ _ritual_config_yaml function function _ritual_config_yaml L135–178
+ _seed_land_check_repo function function _seed_land_check_repo L181–215
+ _seed_via_init function function _seed_via_init L28–48
+ _sync_runner function function _sync_runner L260–271
+ FIXTURES import import FIXTURES L14–14
+ Path import import Path L10–10
+ annotations import import annotations L4–4
+ git_status_runner import import git_status_runner L14–14
+ io import import io L6–6
+ json import import json L7–7
+ kit_root import import kit_root L13–13
+ land_a_fence_body import import land_a_fence_body L14–14
+ land_handover_text import import land_handover_text L14–14
+ land_roadmap_text import import land_roadmap_text L14–14
+ load_config import import load_config L12–12
+ make_runner import import make_runner L14–14
+ ok import import ok L14–14
+ redirect_stdout import import redirect_stdout L9–9
+ run_cli import import run_cli L14–14
+ run_land_check import import run_land_check L25–25
+ seed_land_repo import import seed_land_repo L14–14
+ subprocess import import subprocess L8–8
+ test_governance_sync_dry_run_plans_land_b_when_land_a_and_drifted function function test_governance_sync_dry_run_plans_land_b_when_land_a_and_drifted L274–295
+ test_governance_sync_preserves_land_a_paste_mid_wait function function test_governance_sync_preserves_land_a_paste_mid_wait L298–324
+ test_land_check_refuses_landed_on_post_merge_incomplete function function test_land_check_refuses_landed_on_post_merge_incomplete L233–254
+ test_land_check_refuses_landed_while_land_a function function test_land_check_refuses_landed_while_land_a L218–230
+ test_land_closeout_command_exit_codes function function test_land_closeout_command_exit_codes L85–112
+ test_land_closeout_human_output_frozen_tokens function function test_land_closeout_human_output_frozen_tokens L115–129
+ test_status_exit_0_when_land_a_and_aligned function function test_status_exit_0_when_land_a_and_aligned L70–82
+ test_status_exit_2_post_merge_incomplete_when_land_a_and_d1_drifted function function test_status_exit_2_post_merge_incomplete_when_land_a_and_d1_drifted L51–67
+ Path import import Path L7–7
+ annotations import import annotations L4–4
+ git_status_runner import import git_status_runner L9–9
+ land_a_fence_body import import land_a_fence_body L9–9
+ land_handover_text import import land_handover_text L9–9
+ run_cli import import run_cli L9–9
+ seed_land_repo import import seed_land_repo L9–9
+ time import import time L6–6
+ test_default_status_path_never_invokes_gh function function test_default_status_path_never_invokes_gh L12–30
+ test_status_with_land_closeout_stays_bounded function function test_status_with_land_closeout_stays_bounded L33–46
+ CI_TEMPLATE variable variable CI_TEMPLATE L22–22
+ _adapter function function _adapter L25–34
+ AnchorResult import import AnchorResult L10–10
+ HeadResult import import HeadResult L10–10
+ KIT_ROOT import import KIT_ROOT L11–11
+ LAND_B_REMEDIATION import import LAND_B_REMEDIATION L19–19
+ MagicMock import import MagicMock L7–7
+ Path import import Path L6–6
+ RecordingRunner import import RecordingRunner L9–9
+ StatusResult import import StatusResult L10–10
+ annotations import import annotations L4–4
+ check_land_closeout import import check_land_closeout L20–20
+ land_a_fence_body import import land_a_fence_body L11–11
+ land_closeout_payload import import land_closeout_payload L20–20
+ land_handover_text import import land_handover_text L11–11
+ load_fixture_config import import load_fixture_config L11–11
+ seed_land_repo import import seed_land_repo L11–11
+ write_config import import write_config L11–11
+ test_ci_template_uses_github_token_only_and_never_pushes function function test_ci_template_uses_github_token_only_and_never_pushes L137–145
+ test_fail_closed_on_corrupted_lock function function test_fail_closed_on_corrupted_lock L126–134
+ test_muse_only_never_calls_git_or_gh function function test_muse_only_never_calls_git_or_gh L83–123
+ test_no_write_commands_from_land_closeout function function test_no_write_commands_from_land_closeout L65–80
+ test_remediation_strings_are_never_executed function function test_remediation_strings_are_never_executed L53–62
+ test_report_does_not_echo_handover_secrets function function test_report_does_not_echo_handover_secrets L37–50
+ _adapter function function _adapter L15–24
+ _large_roadmap function function _large_roadmap L27–43
+ AnchorResult import import AnchorResult L10–10
+ HeadResult import import HeadResult L10–10
+ MagicMock import import MagicMock L7–7
+ Path import import Path L6–6
+ RecordingRunner import import RecordingRunner L9–9
+ StatusResult import import StatusResult L10–10
+ annotations import import annotations L3–3
+ check_land_closeout import import check_land_closeout L12–12
+ land_handover_text import import land_handover_text L11–11
+ load_fixture_config import import load_fixture_config L11–11
+ seed_land_repo import import seed_land_repo L11–11
+ time import import time L5–5
+ test_large_queue_and_handover_bounded_and_no_gh function function test_large_queue_and_handover_bounded_and_no_gh L46–69
+ test_large_queue_conflict_still_detected function function test_large_queue_conflict_still_detected L72–81
~ tests/unit/test_land_closeout.py .py 52 symbols added
+ _adapter function function _adapter L40–49
+ _check function function _check L52–55
+ _pr_handover function function _pr_handover L277–281
+ AnchorResult import import AnchorResult L15–15
+ CommandResult import import CommandResult L14–14
+ HeadResult import import HeadResult L15–15
+ LAND_A_MARKER import import LAND_A_MARKER L16–16
+ LAND_B_MARKER import import LAND_B_MARKER L16–16
+ LAND_PHASE_A import import LAND_PHASE_A L27–27
+ LAND_PHASE_B import import LAND_PHASE_B L27–27
+ LAND_PHASE_UNREADABLE import import LAND_PHASE_UNREADABLE L27–27
+ MagicMock import import MagicMock L12–12
+ Path import import Path L11–11
+ RecordingRunner import import RecordingRunner L14–14
+ StatusResult import import StatusResult L15–15
+ annotations import import annotations L9–9
+ check_land_closeout import import check_land_closeout L37–37
+ extract_land_id import import extract_land_id L27–27
+ land_a_fence_body import import land_a_fence_body L16–16
+ land_b_fence_body import import land_b_fence_body L16–16
+ land_complete import import land_complete L37–37
+ land_handover_text import import land_handover_text L16–16
+ land_queue_conflict import import land_queue_conflict L27–27
+ land_roadmap_text import import land_roadmap_text L16–16
+ load_fixture_config import import load_fixture_config L16–16
+ resolve_land_phase import import resolve_land_phase L27–27
+ seed_land_repo import import seed_land_repo L16–16
+ set_marker_land_phase import import set_marker_land_phase L27–27
+ strip_land_parenthetical import import strip_land_parenthetical L27–27
+ write_config import import write_config L16–16
+ test_bare_open_pr_alone_does_not_trigger_land_a function function test_bare_open_pr_alone_does_not_trigger_land_a L181–191
+ test_complete_when_land_b_and_fresh function function test_complete_when_land_b_and_fresh L129–141
+ test_conflicting_vocabulary_is_unreadable function function test_conflicting_vocabulary_is_unreadable L194–202
+ test_historical_other_slice_land_row_does_not_conflict function function test_historical_other_slice_land_row_does_not_conflict L248–258
+ test_land_a_in_progress_when_aligned function function test_land_a_in_progress_when_aligned L84–90
+ test_land_b_in_progress_when_drifted function function test_land_b_in_progress_when_drifted L112–126
+ test_land_id_extraction_strips_parenthetical function function test_land_id_extraction_strips_parenthetical L228–232
+ test_land_phase_conflicts_queue_done_token function function test_land_phase_conflicts_queue_done_token L235–245
+ test_marker_attribute_beats_vocabulary function function test_marker_attribute_beats_vocabulary L205–214
+ test_no_gh_when_probe_disabled function function test_no_gh_when_probe_disabled L309–314
+ test_not_applicable_when_no_land_posture function function test_not_applicable_when_no_land_posture L69–81
+ test_not_applicable_without_lock function function test_not_applicable_without_lock L61–66
+ test_ok_vs_land_complete_distinction function function test_ok_vs_land_complete_distinction L320–325
+ test_post_merge_incomplete_when_d1_drifted function function test_post_merge_incomplete_when_d1_drifted L93–102
+ test_post_merge_incomplete_when_stale_marker function function test_post_merge_incomplete_when_stale_marker L105–109
+ test_probe_merged_pr_catches_hand_edited_alignment function function test_probe_merged_pr_catches_hand_edited_alignment L284–298
+ test_probe_merged_pr_gh_failure_never_fails_open function function test_probe_merged_pr_gh_failure_never_fails_open L301–306
+ test_queue_conflict_requires_land_shaped_row function function test_queue_conflict_requires_land_shaped_row L261–271
+ test_set_marker_land_phase_roundtrip function function test_set_marker_land_phase_roundtrip L217–222
+ test_unreadable_freshness_not_masked_as_post_merge_incomplete function function test_unreadable_freshness_not_masked_as_post_merge_incomplete L153–160
+ test_unreadable_on_unknown_land_phase_value function function test_unreadable_on_unknown_land_phase_value L144–150
+ test_vocabulary_fallback_wait_for_merge_is_land_a function function test_vocabulary_fallback_wait_for_merge_is_land_a L166–178
~ tools/land_closeout/__init__.py .py 5 symbols added
+ __all__ variable variable __all__ L10–15
+ LandCloseoutReport import import LandCloseoutReport L3–3
+ check_land_closeout import import check_land_closeout L3–3
+ land_closeout_payload import import land_closeout_payload L3–3
+ land_complete import import land_complete L3–3
~ tools/land_closeout/check.py .py 40 symbols added
+ CONFLICT_TOKEN variable variable CONFLICT_TOKEN L43–43
+ LAND_B_FINISH_REMEDIATION variable variable LAND_B_FINISH_REMEDIATION L44–47
+ LandCloseoutReport class class LandCloseoutReport L51–69
+ ok method method ok L63–69
+ STATE_COMPLETE variable variable STATE_COMPLETE L40–40
+ STATE_LAND_A_IN_PROGRESS variable variable STATE_LAND_A_IN_PROGRESS L37–37
+ STATE_LAND_B_IN_PROGRESS variable variable STATE_LAND_B_IN_PROGRESS L39–39
+ STATE_NOT_APPLICABLE variable variable STATE_NOT_APPLICABLE L36–36
+ STATE_POST_MERGE_INCOMPLETE variable variable STATE_POST_MERGE_INCOMPLETE L38–38
+ STATE_UNREADABLE variable variable STATE_UNREADABLE L41–41
+ _load_default_lane_docs function function _load_default_lane_docs L274–281
+ _probe_merged_pr function function _probe_merged_pr L253–271
+ _unreadable function function _unreadable L235–250
+ check_land_closeout function function check_land_closeout L80–232
+ CommandRunner import import CommandRunner L18–18
+ GovernanceFreshnessReport import import GovernanceFreshnessReport L21–21
+ LAND_B_REMEDIATION import import LAND_B_REMEDIATION L25–25
+ LAND_PHASE_A import import LAND_PHASE_A L25–25
+ LAND_PHASE_B import import LAND_PHASE_B L25–25
+ LAND_PHASE_UNREADABLE import import LAND_PHASE_UNREADABLE L25–25
+ LockError import import LockError L20–20
+ OverseerConfig import import OverseerConfig L16–16
+ Path import import Path L13–13
+ SubprocessRunner import import SubprocessRunner L18–18
+ VcsAdapter import import VcsAdapter L15–15
+ annotations import import annotations L9–9
+ check_governance_freshness import import check_governance_freshness L21–21
+ create_adapter import import create_adapter L17–17
+ dataclass class import dataclass L12–12
+ extract_land_id import import extract_land_id L25–25
+ extract_paste_pr_number import import extract_paste_pr_number L25–25
+ json import import json L11–11
+ land_queue_conflict import import land_queue_conflict L25–25
+ lane_living_doc_abs import import lane_living_doc_abs L19–19
+ lock_path import import lock_path L20–20
+ read_version_lock import import read_version_lock L20–20
+ resolve_land_phase import import resolve_land_phase L25–25
+ resolve_lane_docs import import resolve_lane_docs L16–16
+ land_closeout_payload function function land_closeout_payload L284–295
+ land_complete function function land_complete L72–77
~ .cursor/skills/governance-sync/SKILL.md .md 1 symbol added, 1 symbol modified
+ Post-merge land closeout (PMHF) section Post-merge land closeout (PMHF) L37–43
~ cli/commands/status.py .py 2 symbols added, 2 symbols modified
+ check_land_closeout import import check_land_closeout L28–28
+ land_closeout_payload import import land_closeout_payload L28–28
~ cli/main.py .py 1 symbol added, 3 symbols modified
+ run_land_closeout_command import import run_land_closeout_command L40–40
~ main
~ cursor/skills/governance-sync/SKILL.md .md 1 symbol added, 1 symbol modified
+ Post-merge land closeout (PMHF) section Post-merge land closeout (PMHF) L37–43
~ docs/OVERSEER-HANDOVER.md .md 9 symbols added, 9 symbols removed, 7 symbols modified
NEXT SESSION — PMHF-b Auto build (post-merge handover freshness) section NEXT SESSION — PMHF-b Auto build (post-merge handover freshness) L10–85
Authority split (read this — three different handovers) section Authority split (read this — three different handovers) L20–28
table section table L22–27
Paste-ready prompt — PMHF-b section Paste-ready prompt — PMHF-b L49–85
code[text] variable variable code[text] L51–82
THE ONE NEXT STEP — Model: Auto section THE ONE NEXT STEP — Model: Auto L36–49
table section table L41–48
What just landed section What just landed L28–36
table section table L30–35
+ NEXT SESSION — PMHF → main (land-a) section NEXT SESSION — PMHF → main (land-a) L10–78
+ Authority split (read this — three different handovers) section Authority split (read this — three different handovers) L22–30
+ table section table L24–29
+ Paste-ready prompt — PMHF → main (land-a) section Paste-ready prompt — PMHF → main (land-a) L52–78
+ code[text] variable variable code[text] L54–75
+ THE ONE NEXT STEP — Model: Operator + Auto section THE ONE NEXT STEP — Model: Operator + Auto L38–52
+ table section table L44–51
+ What just landed section What just landed L30–38
+ table section table L32–37
~ table
~ table
~ table
~ tests/support.py .py 7 symbols added
+ LAND_A_MARKER variable variable LAND_A_MARKER L211–213
+ LAND_B_MARKER variable variable LAND_B_MARKER L214–216
+ land_a_fence_body function function land_a_fence_body L219–235
+ land_b_fence_body function function land_b_fence_body L238–251
+ land_handover_text function function land_handover_text L254–313
+ land_roadmap_text function function land_roadmap_text L316–335
+ seed_land_repo function function seed_land_repo L338–369
~ tools/close_ritual/land_check.py .py 2 symbols added, 1 symbol modified
+ _closeout_gate function function _closeout_gate L343–378
+ check_land_closeout import import check_land_closeout L15–15
~ tools/governance_hygiene/engine.py .py 1 symbol added, 3 symbols modified
+ extract_paste_ready_block import import extract_paste_ready_block L16–16
+ LAND_A_VOCABULARY variable variable LAND_A_VOCABULARY L51–58
+ LAND_B_REMEDIATION variable variable LAND_B_REMEDIATION L65–68
+ LAND_B_VOCABULARY variable variable LAND_B_VOCABULARY L59–62
+ LAND_PHASE_A variable variable LAND_PHASE_A L45–45
+ LAND_PHASE_B variable variable LAND_PHASE_B L46–46
+ LAND_PHASE_UNREADABLE variable variable LAND_PHASE_UNREADABLE L47–47
+ LandBPlan class class LandBPlan L191–195
+ REASON_LAND_A_WAIT variable variable REASON_LAND_A_WAIT L32–32
+ REASON_LAND_PHASE_UNREADABLE variable variable REASON_LAND_PHASE_UNREADABLE L33–33
+ _GENERIC_LAND_TOKENS variable variable _GENERIC_LAND_TOKENS L80–80
+ _LAND_ID_LINE_RE variable variable _LAND_ID_LINE_RE L74–74
+ _LAND_PARENTHETICAL_RE variable variable _LAND_PARENTHETICAL_RE L76–76
+ _LAND_PHASE_ATTR_RE variable variable _LAND_PHASE_ATTR_RE L70–70
+ _NEXT_ID_CELL_RE variable variable _NEXT_ID_CELL_RE L75–75
+ _PASTE_FENCE_RE variable variable _PASTE_FENCE_RE L71–73
+ _PASTE_PR_RE variable variable _PASTE_PR_RE L77–77
+ _meaningful_land_tokens function function _meaningful_land_tokens L138–140
+ _slice_from_land_id function function _slice_from_land_id L198–206
+ extract_land_id function function extract_land_id L120–130
+ extract_paste_fence_body function function extract_paste_fence_body L83–86
+ extract_paste_pr_number function function extract_paste_pr_number L169–175
+ land_queue_conflict function function land_queue_conflict L143–166
+ plan_land_b function function plan_land_b L209–232
+ render_land_b_next_session function function render_land_b_next_session L235–263
+ render_land_b_paste function function render_land_b_paste L266–292
+ resolve_land_phase function function resolve_land_phase L89–117
+ set_marker_land_phase function function set_marker_land_phase L178–187
+ strip_land_parenthetical function function strip_land_parenthetical L133–135
~ tools/governance_hygiene/patch.py .py 12 symbols added, 7 symbols modified
+ LAND_PHASE_A import import LAND_PHASE_A L12–12
+ LAND_PHASE_B import import LAND_PHASE_B L12–12
+ LAND_PHASE_UNREADABLE import import LAND_PHASE_UNREADABLE L12–12
+ NextRegenDecision import import NextRegenDecision L12–12
+ REASON_LAND_A_WAIT import import REASON_LAND_A_WAIT L12–12
+ REASON_LAND_PHASE_UNREADABLE import import REASON_LAND_PHASE_UNREADABLE L12–12
+ extract_paste_pr_number import import extract_paste_pr_number L12–12
+ plan_land_b import import plan_land_b L12–12
+ render_land_b_next_session import import render_land_b_next_session L12–12
+ render_land_b_paste import import render_land_b_paste L12–12
+ resolve_land_phase import import resolve_land_phase L12–12
+ set_marker_land_phase import import set_marker_land_phase L12–12

0 comments

No comments yet. Be the first to start the discussion.

To add a comment, use the Muse CLI: muse hub commit comment sha256:72efabb7bebf54347c1e4ac4368f3c01c89074a555c4eb0fcfbe9680c3d457c3 --body "your comment"