PHASE-PMHF-POST-MERGE-HANDOVER-FRESHNESS.md markdown
598 lines 31.6 KB
Raw
sha256:a78e7e5a8740e03315f325d19edeb3aa1b306b3337d04abbaa9a9e0f3bbeb7a1 docs: MuseHub-first before ISR #74 — staging solidify NEXT Human 1 day ago

Phase PMHF — Post-merge handover freshness (platform-neutral closeout)

Status: Reviewed → pass (PMHF-r4). PMHF-a is spec-only and now frozen; no code lands in this phase. PMHF-b (Auto) is cleared to build mechanically against this frozen contract.

phase: PMHF
outputs:
- id: pmhf-post-merge-handover-freshness
  path: docs/archive/phases/PHASE-PMHF-POST-MERGE-HANDOVER-FRESHNESS.md
  frozen: true
frozen_inputs:
- id: gfg-freshness-gate
  path: docs/archive/phases/PHASE-GFG-GOVERNANCE-FRESHNESS-GATE.md
- id: phase-9a5-triggers
  path: docs/archive/phases/PHASE-9A-5-GOVERNANCE-HYGIENE-AGENT-OUTLINE.md
- id: gs-paste-ready-regen
  path: docs/archive/phases/PHASE-GS-PASTE-READY-REGEN.md
- id: kh1-relay-standard
  path: docs/archive/phases/PHASE-KH1-HANDOVER-RELAY-STANDARD.md
- id: close-ritual-land-check
  path: tools/close_ritual/land_check.py
- id: governance-freshness-probe
  path: tools/governance_freshness/check.py
- id: governance-hygiene-drift
  path: tools/governance_hygiene/drift.py
- id: next-regen
  path: tools/governance_hygiene/next_regen.py
- id: status-exit-code
  path: cli/commands/status.py
- id: decision-tiers
  path: policy/tiers.yaml
- id: kit-spec-freeze-policy
  path: docs/OVERSEER-KIT-SPEC.md#6
- id: test-tiers
  path: policy/test-tiers.yaml
review_stamp:
  reviewed_at: '2026-07-31T12:28:43Z'
  verdict: pass
  reviewer_mode: agent
  reviewer_model: thinking-high
  reviewer_provider: local
  kit_version: 0.1.0
  artifact_digest: sha256:7d02bb23779a67015f423e95aa4adca2803d3aeeba1a201fb291f514b2bf6986

Downstream edge: PMHF-b treats this document as ground truth without re-deriving it (SPEC §6 mandatory reviewed freeze). It closes the permanent gap left when GFG detect-only (ok status --exit-code → exit 2 on D1) and optional Cursor session-end Automation do not force a post-merge living-doc closeout — the exact consumer incident after bornfree-hub SF-4 / PR #206: merge lands on GitHub, handover paste stays “open PR / wait for merge,” agents re-paste the stale prompt.

Review record (§6.2): every freeze-review finding MUST cite file+line per SPEC §6; uncited findings are invalid and are discarded. Fixes during the loop are Tier 1 (feature branch); merge to main is Tier 3 and is never part of this loop.

Round Reviewer Verdict Resolution
PMHF-r1 Freeze-review loop (checklist + thinking, thinking-high) findings Checklist dry-run pending stamp. Semantic: R1-M1 §PMHF.4.2 bare open PR false-positives normal feature pastes (templates/OVERSEER-HANDOVER.template.md / SD-17 language); R1-M2 bare Operator Model label not in policy/model-labels.yaml labels (only Operator + Auto); R1-M3 §PMHF.3.3 “land complete” used report.ok which includes land_a_in_progress — contradicts §PMHF.5 stricter complete rule; R1-M4 must explicitly amend GFG §GFG.3#4 “no on-merge Automation” for optional GitHub Actions (not git hook / not Cursor); R1-M5 §PMHF.3.3 roadmap-DONE-while-land-a needs a concrete closeout check not soft prose; R1-N1 name exact template/skill touchpoint paths in §PMHF.11. Fixed in-doc.
PMHF-r2 Freeze-review loop (checklist + thinking, thinking-high) findings R2-M1 matching land queue row for land_phase_conflicts_queue_done underspecified; R2-M2 freshness unreadable must not be masked as post_merge_incomplete. Fixed in-doc.
PMHF-r3 Freeze-review loop (checklist + thinking, thinking-high) findings R3-M1 §PMHF.3.3 criterion 2 (any row containing → main) false-matches historical DONE land rows (docs/ROADMAP.md GS-PASTE → main, GFG → main, …) while a new land-a is in progress — narrow to phase_tokens intersection only. Fixed in-doc.
PMHF-r4 Freeze-review loop (checklist + thinking, thinking-high) pass Checklist gate clean (0 findings). Semantic re-read: R1-M1–M5 / R1-N1 / R2-M1–M2 / R3-M1 RESOLVED; land-a/land-b protocol + land_complete vs ok distinction precise; vocabulary excludes bare open PR; queue-DONE conflict uses phase_tokens only; GFG amendment note holds (optional Actions ≠ Cursor/git on-merge primary); no security/irreversible/real_money/gates_tier3 escalation (Tier-1 CLI + Tier-2 optional CI enable). Stamp written by ok review --freeze.

§PMHF.0 — Simple summary

When a branch is ready to land, someone opens a pull request and waits for a human (or an authorized land) to merge it. After the merge, the living notes — roadmap and handover — must be updated so the “what’s next” box no longer says “wait for merge.” Today the kit can notice that those notes are stale (ok status already fails), but nothing in the land protocol requires a second paste step to fix them, and Cursor session-end Automation is not an acceptable primary fix because the kit must work on any platform.

PMHF freezes a platform-neutral closeout: land is two paste steps (land-a then land-b); CLI surfaces refuse “land complete / all clear” until the handover NEXT matches post-merge reality; optional GitHub Actions may comment or open a docs PR with a governance-sync plan — never silent writes to main, never Cursor-only.

Technical summary: compose with GFG (D1/D2 + marker) and GS-PASTE (next_regen). Add machine-readable land-phase on the existing overseer:next marker; freeze land-a / land-b paste shapes; add tools/land_closeout/ (LandCloseoutReport / check_land_closeout); wire fail-closed into ok status --exit-code, enabled ok land-check, and thin ok land-closeout; extend governance-sync / next_regen so a post-merge plan prefers land-b NEXT; ship opt-in templates/ci/governance-closeout-github-actions.yml. No redesign of freeze review or build-verification. No Cursor Automation as primary trigger.


§PMHF.1 — Scope

In scope (PMHF-a freezes; PMHF-b implements):

  1. Two-step land protocol (land-a / land-b) in templates, skills/rules touchpoints, and next_regen emission rules (§PMHF.3).
  2. Machine-readable land-phase attribute on the existing NEXT HTML marker (§PMHF.4).
  3. LandCloseoutReport + check_land_closeout resolution rules (§PMHF.5).
  4. Fail-closed wiring: ok status --exit-code, ok land-check (when enabled), new ok land-closeout (§PMHF.6).
  5. Optional CI template: push/merge to main → comment or open docs PR with dry-run plan (§PMHF.7).
  6. Explicit non-goals (§PMHF.2), boundary table (§PMHF.8), consumer migration (§PMHF.9), seven-tier matrix (§PMHF.10), Auto deliverables (§PMHF.11).

Out of scope (explicit non-goals — prevent creep):

Non-goal Why rejected
Cursor session-end Automation as primary closeout Kit must work on Copilot, Claude Code, CI, and any chat. Cursor Automation may remain a secondary degrade (GFG already ships the template); it is not the primary loop closer.
Silent writes / commits to main after merge SD-14 / Tier 3. CI and CLI never patch living docs on main in place. Apply stays feature-branch (or docs PR from a branch). Merging a docs-only PR to main remains operator policy (existing no-docs-only-PR-to-main rule when deploys are paid) — PMHF CI may open a branch PR; it must not auto-merge.
Git post-merge hook as primary trigger Already REJECTED in 9A-5 §1 / GFG §GFG.2 — does not fire for GitHub-side merges; invisible per-clone; fails muse-only.
Reopening GFG’s Cursor/git on-merge Automation as primary GFG §GFG.3 rule 4 forbids on-merge Automation as GFG’s primary. PMHF does not add Cursor/git on-merge Automation. It adds an optional GitHub Actions template (§PMHF.7) as a platform-neutral nudge — comment or feature-branch docs PR only.
Redesign of freeze review or build-verification Out of incident scope. /freeze-review-loop and /build-verification-review stay as frozen.
Redefining D1/D2/D3 semantics Reuse GFG + tools/governance_hygiene/drift.py. PMHF adds land-phase posture + closeout state on top.
Making close_ritual.enabled: true the default Consumer posture flip is Tier 3 / out of kit Auto. Status + ok land-closeout are the always-on floor.
Requiring gh for the always-on status floor Status must remain usable offline relative to GitHub PR listing (same posture as GFG §GFG.4.1). Optional PR-merged enrichment is best-effort when gh is available (§PMHF.5.3).
Auto-merge or ok pr-land redesign Land merge authority stays SD-21 / Tier 3 / existing ok pr-land.
Hosted dashboard / Track Q / product runtime changes Kit governance only.
One-off hand-edit of a single consumer handover as the “fix” Symptom patch; next land recreates the gap.

§PMHF.2 — Incident → permanent gap (verified, do not redesign)

Fact Evidence
GFG fail-closes ok status --exit-code on D1/D2 / stale marker docs/archive/phases/PHASE-GFG-GOVERNANCE-FRESHNESS-GATE.md §GFG.4–§GFG.6; live governance_freshness: drifted
GFG primary secondary trigger is Cursor session-end Automation template §GFG.3; user rejects Cursor-only as primary for this incident class
GFG explicitly rejected git post-merge hook and silent main writes §GFG.2 / §GFG.11
GS-PASTE regenerates NEXT + paste via governance-sync only docs/archive/phases/PHASE-GS-PASTE-READY-REGEN.md; tools/governance_hygiene/next_regen.py
ok land-check can report landed: true while ignoring land-phase posture tools/close_ritual/land_check.py — path hash match + GFG freshness when enabled; no NEXT posture
Land sessions stop for Tier 3 human merge; merge happens on GitHub SD-21 / Tier 3; bornfree-hub SF-4 / PR #206 class of failure
After merge, paste stays “open PR / wait for merge”; agents re-paste Handover NEXT not split into land-a / land-b; detect ≠ closeout

PMHF must not reopen GFG’s D1/D2 rules, marker format, or exit-code precedence renumbering. It adds the missing land protocol, NEXT posture, land-complete refusal, and optional CI nudge.

Frozen amendment note vs GFG §GFG.3 rule 4: GFG forbids shipping an on-merge Automation that pretends to replace session-end + CLI for freshness. PMHF’s §PMHF.7 GitHub Actions template is not that Automation: it is optional, never Cursor-only, never a git hook, never writes main, and never clears local freshness by itself — agents still run land-b / ok governance-sync / ok land-closeout. GFG detect floor stays authoritative for D1/D2/marker.


§PMHF.3 — Land = two paste steps (frozen protocol)

Land is incomplete until both steps are done.

§PMHF.3.1 — land-a (PR + stop for merge)

Purpose: Open or update the land PR (or run SD-21 finish-mode land hygiene through the authorized merge path), then stop for Tier 3 human merge when SD-21 criteria are not met.

Frozen paste shape (required fields inside the paste-ready fence):

Model: Operator + Auto
ID: <slice> → main (land-a)
land-phase: land-a

Deliver:
1. Open/update PR (or SD-21 Muse→mirror→GitHub main path when criteria hold)
2. Stop for Tier 3 merge authorization when required
3. Do NOT claim land complete
4. Do NOT regenerate post-merge NEXT in this paste

After merge is confirmed on main: paste land-b (same slice). Land is incomplete until land-b.

Model label: exactly Operator + Auto from policy/model-labels.yaml (no bare Operator — that display value is not a valid label). Never emit a combined “merge + sync docs” single paste that agents treat as done after opening the PR.

§PMHF.3.2 — land-b (post-merge roadmap + handover sync)

Purpose: After main has advanced (merge confirmed), sync living docs so NEXT matches reality.

Frozen paste shape:

Model: Auto
ID: <slice> land-b (post-merge sync)
land-phase: land-b

Deliver:
1. Fetch/pull latest main (regime-appropriate)
2. ok governance-sync --dry-run then apply when the plan is correct
3. Regenerate NEXT + paste so they no longer say wait-for-merge / land-a
4. Feature-branch commit bundling ROADMAP + HANDOVER (SD-17); open docs PR if needed
5. ok status --exit-code → 0 and ok land-closeout → 0 before claiming land complete

Hard stops: no silent commits to main; no Cursor-only dependency; no freeze/BV redesign.

§PMHF.3.3 — Completeness rule (frozen)

Define land_complete(report, freshness) (stricter than report.ok — see §PMHF.5):

land_complete = freshness.ok AND (
  report.state == "complete"
  OR (report.state == "not_applicable" AND freshness.ok)
)

land_a_in_progress has report.ok == True (status must not false-fail while waiting for merge) but land_complete is False.

Claim Allowed only when
“PR opened / waiting for merge” land-phase=land-a and state is land_a_in_progress
“Land complete” / “all clear after land” land_complete(...) is true
Queue row {slice} → mainDONE land_complete(...) is true and handover land-phase is not land-a

Roadmap may keep a single {slice} → main row; the handover MUST expose land-a then land-b as sequential THE ONE NEXT STEPs.

Frozen check (PMHF-b must implement): check_land_closeout (and therefore ok land-closeout / enabled ok land-check) returns unreadable with message token land_phase_conflicts_queue_done when the default-lane roadmap has a matching land queue row with status DONE/MERGED while handover land-phase=land-a.

Matching land queue row (frozen): a build-queue row where normalize_status(row.status) in {DONE, MERGED} and phase_tokens(row.phase) intersects phase_tokens derived from the land-a NEXT ID cell / paste ID: line (reuse tools/governance_hygiene/parse.py phase_tokens).

Before tokenizing the land-a ID, strip a trailing (land-a) / (land-b) parenthetical (case-insensitive) so PMHF → main (land-a) tokens align with queue row PMHF → main.

Rejected match rule: do not treat “any DONE row whose phase contains → main” as a match — that false-fires against historical land rows (e.g. GS-PASTE → main DONE while a new slice’s land-a is current).

Agents must not mark the land queue row DONE until land-b clears land-phase.

§PMHF.3.4 — next_regen / governance-sync emission (frozen)

When ok governance-sync plans NEXT regeneration (GS-PASTE):

  1. If current handover NEXT marker has land-phase=land-a and closeout state would be post_merge_incomplete (main advanced / D1 drifted / optional merged-PR signal) → emit land-b paste for the same slice (do not re-emit land-a).
  2. If current NEXT is land-b and D1/D2 become aligned after apply → emit the next unambiguous open queue row (or idle / human_authorship_required per GS-PASTE ambiguity rules).
  3. Ambiguity remains fail-closed (next_regen: human_authorship_required) — never invent a product NEXT.
  4. Dry-run shows the planned land-b body; apply writes only on non-dry-run (marker stamp carve-out from GFG unchanged).

§PMHF.4 — Machine-readable land-phase (frozen)

§PMHF.4.1 — Marker attribute

Extend the existing NEXT marker (KH1 / GS-PASTE), do not invent a second marker family:

<!-- overseer:next role=primary lane=product status=live land-phase=land-a -->
Attribute Values Required?
land-phase land-a | land-b Optional on non-land NEXT; required on land-a and land-b pastes

Absent land-phase → non-land NEXT (normal queue work). Unknown values → fail closed as unreadable for land_closeout (do not treat as ok).

§PMHF.4.2 — Closed vocabulary fallback (legacy handovers)

When the marker lacks land-phase, scan only the paste-ready fence body (not the whole handover), case-insensitive.

Treat posture as land-a when any of these frozen substrings match:

  • land-phase: land-a
  • wait for merge
  • awaiting merge
  • stop for Tier 3 merge
  • → main (land-a)
  • (land-a) as an ID/title token (e.g. ID: … (land-a))

Explicitly excluded (do not treat as land-a alone — false-positive on ordinary feature work / SD-17 language):

  • bare open PR / open/update PR / feature branch → PR
  • Tier 3 without the full stop for Tier 3 merge phrase

Treat as land-b when fence contains land-phase: land-b or land-b (post-merge sync).

If both land-a and land-b vocabularies match → unreadable (fail closed; force human fix).

PMHF-b must prefer the HTML attribute when present; vocabulary fallback is for pre-PMHF consumer handovers (bornfree-class). Bornfree “wait for merge” pastes match without needing the HTML attribute.


§PMHF.5 — LandCloseoutReport + check_land_closeout (frozen)

New module tools/land_closeout/ (sibling to tools/governance_freshness/):

@dataclass(frozen=True)
class LandCloseoutReport:
    state: str
    # not_applicable | land_a_in_progress | post_merge_incomplete |
    # land_b_in_progress | complete | unreadable
    message: str
    remediation: str | None
    land_phase: str | None  # land-a | land-b | None
    freshness_ok: bool
    d1: str | None
    optional_pr_merged: bool | None  # None = not probed

    @property
    def ok(self) -> bool:
        return self.state in {"not_applicable", "land_a_in_progress", "complete"}


def check_land_closeout(
    config: OverseerConfig,
    repo_root: Path,
    *,
    adapter: VcsAdapter | None = None,
    runner: CommandRunner | None = None,
    probe_merged_pr: bool = False,
) -> LandCloseoutReport:
    ...

ok semantics (frozen):

  • not_applicable — no land posture; closeout N/A → ok for this probe.
  • land_a_in_progress — waiting for merge; D1 still aligned with current main tip → ok for status floor (must not fail the whole tree while human merge is pending).
  • post_merge_incomplete / land_b_in_progress / unreadablenot ok.
  • complete → ok.

“Land complete / all clear” (stricter than report.ok): allowed only when state == "complete" or (state == "not_applicable" and freshness ok).
land_a_in_progress is not land complete.

§PMHF.5.1 — Reads (frozen)

  1. Reuse check_governance_freshness for D1/D2/marker (no re-derivation of GFG rules).
  2. Read default-lane handover text; parse land-phase from NEXT marker; apply §PMHF.4.2 fallback.
  3. Do not call gh unless probe_merged_pr=True (§PMHF.5.3).
  4. Unreadable handover / marker parse failure → state="unreadable".

§PMHF.5.2 — Resolution order (frozen)

  1. If config/repo cannot load → unreadable.
  2. If not initialized (no version.lock) → not_applicable.
  3. Compute freshness via GFG probe; record freshness_ok, d1. If freshness state == "unreadable"unreadable (do not mask as post_merge_incomplete).
  4. Resolve land_phase (§PMHF.4).
  5. If land_phase == "land-a" and a matching land queue row exists per §PMHF.3.3 → unreadable with message token land_phase_conflicts_queue_done. Do not treat as complete.
  6. If land_phase is None → not_applicable (this probe does not override GFG; status still applies GFG independently).
  7. If land_phase == "land-a":
    • If d1 == "drifted" OR freshness state in {drifted, stale_marker} OR optional_pr_merged is True → post_merge_incomplete. Remediation (frozen string prefix):
      land-b required: ok governance-sync --dry-run then apply; paste land-b; do not re-paste land-a.
    • Else → land_a_in_progress.
  8. If land_phase == "land-b":
    • If freshness not ok OR d1 == "drifted"land_b_in_progress with remediation to finish governance-sync apply + clear land-phase.
    • Else → complete.
  9. Else → unreadable.

§PMHF.5.3 — Optional merged-PR enrichment (frozen)

When probe_merged_pr=True and gh is available and the paste fence names PR #<digits>:

  • If that PR is merged on the configured remote → treat as merge reflected (optional_pr_merged=True), even if D1 was hand-edited back to aligned.
  • If gh missing/fails → leave optional_pr_merged=None; do not fail open to complete.

Default for ok status --exit-code: probe_merged_pr=False (offline floor).
Default for ok land-closeout: probe_merged_pr=True when regime is not muse-only; False for muse-only (no git/gh).
CI template: may pass --probe-merged-pr.

§PMHF.5.4 — Composition with GFG (frozen)

Surface GFG PMHF land_closeout
D1/D2/marker Authority Consumer of GFG report
Mid-land wait (land-a, D1 aligned) ok land_a_in_progress (ok for status)
Post-merge stale NEXT (land-a, D1 drifted) exit 2 post_merge_incomplete + land-b remediation
Hand-edited VCS SHA, land-a remains, PR merged may look ok Caught when probe_merged_pr true; else CI nudge + land-check refusal
Circular wiring into governance-sync Forbidden (GFG) Still forbidden — sync must run to repair

§PMHF.6 — Fail-closed CLI wiring (frozen)

Reuse exit code 2. Do not renumber 2 > 6 > 35 > 3 > 0.

§PMHF.6.1 — ok status / ok status --exit-code

  • Always compute check_land_closeout(..., probe_merged_pr=False) when initialized (additive).
  • JSON key:
    land_closeout: {state, ok, message, remediation, land_phase, freshness_ok, d1, optional_pr_merged}.
  • Human mode: print a line when not report.ok (mirror GFG / muse_sync).
  • --exit-code: fold land_closeout_ok into the top tier with existing conditions:
    … or not governance_freshness_ok or not land_closeout_ok → 2.
    Because land_a_in_progress has ok=True, waiting for merge does not false-fail status.
  • Plain ok status without --exit-code still exits 0.

§PMHF.6.2 — ok land-check

When close_ritual.enabled: false, keep today’s no-op exit 0 (unchanged).

When enabled, after path checks + GFG freshness (§GFG.6):

  1. Run check_land_closeout with probe_merged_pr=True (git regimes).
  2. Set landed=True only when path checks pass and freshness ok and land_closeout state is complete or not_applicable.
  3. If state is land_a_in_progress, post_merge_incomplete, or land_b_in_progresslanded=False, exit 2, emit remediation (never merge).

§PMHF.6.3 — ok land-closeout (new thin command)

Item Rule
Command ok land-closeout [--json] [--probe-merged-pr]
Behavior Print LandCloseoutReport; exit 0 if report.ok else 2
Merge Never
Doc writes Never
Purpose Agent/CI choke point with explicit land-b remediation; platform-neutral

--probe-merged-pr forces enrichment on; --no-probe-merged-pr disables. Default per §PMHF.5.3.

§PMHF.6.4 — Surfaces that must NOT gain circular fail-closed

Surface Rule
ok governance-sync Must still run when land_closeout incomplete (it is the repair tool).
ok review --freeze Not wired (same as GFG).

§PMHF.6.5 — Refusal strings (frozen tokens)

Emit these human-visible tokens (exact) when refusing land complete:

  • land_closeout: post_merge_incomplete
  • land_closeout: land_b_in_progress
  • land_closeout-remediation: land-b required: ok governance-sync --dry-run then apply; paste land-b; do not re-paste land-a

Never emit “all clear” / landed: true / land complete while those states hold.


§PMHF.7 — Optional CI on push/merge to main (frozen)

Ship a template only (opt-in; not auto-enabled for all consumers):

Path: templates/ci/governance-closeout-github-actions.yml

Frozen behavior:

on:
  push:
    branches: [main]   # or repo main_branch name documented in header comments
  workflow_dispatch:

Job steps (normative intent — PMHF-b may use current actions/checkout / setup-python majors):

  1. Checkout main at the push SHA.
  2. Install CLI deps (PyYAML) — same pattern as freeze-review CI template.
  3. Run ok governance-sync --dry-run (and optionally ok land-closeout --probe-merged-pr).
  4. If dry-run reports D1/D2 drift or land_closeout not ok:
    • Comment on the push commit (or associated merged PR when detectable) with the dry-run plan summary + frozen remediation pointing to land-b paste; or
    • Open a docs PR from an auto branch (e.g. chore/governance-closeout-<shortsha>) that contains only the planned living-doc patch after an explicit apply in CI is forbidden on main. Preferred v1: comment-only with the plan; opening a docs PR is allowed only if the workflow commits to a feature branch and opens PR → main (never direct push to main).
  5. Workflow exit non-zero when closeout incomplete so the check is visible — but never treat CI unavailability as pass for local agents (degrade: run ok land-closeout locally).

Frozen bans:

  • No git push to main from this workflow.
  • No applying governance-sync patches directly onto main in CI.
  • No Cursor-only steps.
  • No secrets beyond standard GITHUB_TOKEN for comment/PR.

Kit dogfood may vendor a disabled example under .github/workflows/ only if clearly marked optional; default remains template-under-templates/ci/ like freeze-review.


§PMHF.8 — Boundary table (frozen)

Scenario Caught / closed by PMHF?
Merge on GitHub; NEXT still land-a; D1 drifted; ok status --exit-code Yes — GFG + post_merge_incomplete remediation → land-b
Agent re-pastes land-a after merge Yes — protocol forbids; CLI remediation says do not re-paste land-a; land-check refuses landed
Cursor Automations unavailable Non-blocking — CLI + optional CI remain primary
Mid-land wait; land-a; D1 aligned No false fail on status — land_a_in_progress ok
Hand-edit VCS SHA; land-a remains; PR merged; gh available Yes via ok land-closeout --probe-merged-pr
Same hand-edit; offline; no gh Partial — status may be green; land-check (enabled) still refuses landed while land-a; CI comment nudges
Silent main doc rewrite from CI Forbidden
Freeze / BV redesign Out of scope
muse-only (no git/gh) land-phase + freshness via Muse tip; no gh probe; CI template N/A

§PMHF.9 — Consumer migration notes (frozen honesty)

After PMHF-b merges and consumers ok sync:

  1. No required config block for the status / land-closeout floor (always-on when initialized).
  2. Existing land NEXT pastes without land-phase= keep working via §PMHF.4.2 vocabulary fallback.
  3. Operators should split any living “→ main / wait for merge” NEXT into land-a then land-b on the next land (template + regen will emit the attribute going forward).
  4. Optional: copy templates/ci/governance-closeout-github-actions.yml into .github/workflows/ (Tier 2 confirm-once to enable). Not required for CLI floor.
  5. close_ritual.enabled: false consumers still get status + ok land-closeout; land-check posture refusal applies only when enabled (unchanged GFG split).
  6. One-time: if currently D1-drifted with stale wait-for-merge NEXT, run land-b (ok governance-sync --dry-run → apply) — do not re-paste land-a.
  7. Blast radius: workflows that claimed “landed” solely from path hashes while NEXT said wait-for merge will start seeing land-check / land-closeout exit 2. That is intended.

§PMHF.10 — Seven-tier test matrix (PMHF-b Auto must satisfy)

Tier Proves
unit check_land_closeout resolution table: not_applicable / land_a_in_progress / post_merge_incomplete (D1 drifted) / post_merge_incomplete (stale_marker) / land_b_in_progress / complete / unreadable (bad land-phase) / vocabulary fallback land-a (wait for merge) / bare open PR alone does not trigger land-a / conflict vocab → unreadable / land_phase_conflicts_queue_done (token intersection) / historical other-slice → main DONE does not conflict; ok vs land_complete distinction; marker attribute beats vocabulary.
integration ok status --json --exit-code2 with land_closeout.state=post_merge_incomplete when land-a + D1 drifted; → 0 when land-a + D1 aligned (land_a_in_progress); ok land-closeout exit codes; ok land-check with ritual enabled refuses landed for land-a and post_merge_incomplete; governance-sync dry-run plans land-b NEXT when land-a + D1 drifted.
e2e Fixture cycle: land-a NEXT + aligned main → status 0 → advance main tip → status 2 + land-b remediation → governance-sync apply → land-phase cleared/complete → status 0 + land-closeout 0.
stress Large handover (200+ queue rows) — land_closeout parse + freshness compose finishes bounded; no gh when probe false.
data-integrity land-closeout and status never write docs; CI template contains no apply-to-main step; dry-run governance-sync still only stamps local marker per GFG carve-out.
performance Default status path adds no gh invocation for land_closeout (probe_merged_pr=False).
security No secrets in report; remediation strings non-executed; muse-only never calls git/gh; CI template uses GITHUB_TOKEN only; fail-closed unreadable; no silent main write path.

§PMHF.11 — PMHF-b Auto deliverables (exact)

  1. tools/land_closeout/ (__init__.py, report + check_land_closeout) per §PMHF.5.
  2. cli/commands/land_closeout.py + cli/main.py registration for ok land-closeout.
  3. cli/commands/status.py additive JSON/human + --exit-code fold per §PMHF.6.1.
  4. tools/close_ritual/land_check.py landed refusal per §PMHF.6.2.
  5. tools/governance_hygiene/next_regen.py (+ patch/engine wiring as needed) land-b emission per §PMHF.3.4; marker land-phase= support per §PMHF.4.
  6. Minimal template/skill/rule touchpoints (exact paths):
    • templates/OVERSEER-HANDOVER.template.md — land-a / land-b paste shape note (or short subsection under regeneration rules)
    • cursor/skills/governance-sync/SKILL.md (+ twin .claude/skills/governance-sync/SKILL.md if footprint copies it) — land-b remediation one-liner when land-a + drift
    • .cursor/rules/tier-authority.mdc (and twin if present) — one line: land incomplete until land-b; no claim of land complete while ok land-closeout fails
  7. templates/ci/governance-closeout-github-actions.yml per §PMHF.7.
  8. SPEC §5 additive rows for ok land-closeout + status land_closeout key (additive only).
  9. Seven-tier tests under tests/ covering §PMHF.10 (include land_phase_conflicts_queue_done + vocabulary false-positive exclusions).
  10. Kit ROADMAP + HANDOVER updated together; /build-verification-reviewpass before ROADMAP PMHF-b → DONE.
  11. No Cursor-only primary path; no silent main writes; no freeze/BV redesign.

§PMHF.12 — Hard stops (unchanged)

  • No kit main merge without Tier 3 / SD-21 criteria.
  • No consumer posture/env flips; no secrets; no real money.
  • No Cursor Automation as the primary closeout.
  • No silent writes on main.
  • No redesign of /freeze-review-loop or /build-verification-review.

Cross-references

  • docs/archive/phases/PHASE-GFG-GOVERNANCE-FRESHNESS-GATE.md — detect floor this phase closes into a loop.
  • docs/archive/phases/PHASE-9A-5-GOVERNANCE-HYGIENE-AGENT-OUTLINE.md §1 — trigger rejections this phase respects.
  • docs/archive/phases/PHASE-GS-PASTE-READY-REGEN.md — NEXT/paste regen surface land-b reuses.
  • docs/archive/phases/PHASE-KH1-HANDOVER-RELAY-STANDARD.md — NEXT / paste shape.
  • docs/OVERSEER-KIT-SPEC.md §6 — Freeze-Contract review policy.
  • policy/tiers.yaml — SD-21 finish-mode land hygiene vs Tier 3 merge.
  • templates/ci/freeze-review-github-actions.yml — CI template precedent.
File History 1 commit
sha256:a78e7e5a8740e03315f325d19edeb3aa1b306b3337d04abbaa9a9e0f3bbeb7a1 docs: MuseHub-first before ISR #74 — staging solidify NEXT Human 1 day ago