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):
- Two-step land protocol (land-a / land-b) in templates, skills/rules touchpoints, and
next_regenemission rules (§PMHF.3). - Machine-readable
land-phaseattribute on the existing NEXT HTML marker (§PMHF.4). LandCloseoutReport+check_land_closeoutresolution rules (§PMHF.5).- Fail-closed wiring:
ok status --exit-code,ok land-check(when enabled), newok land-closeout(§PMHF.6). - Optional CI template: push/merge to
main→ comment or open docs PR with dry-run plan (§PMHF.7). - 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} → main → DONE |
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):
- If current handover NEXT marker has
land-phase=land-aand closeout state would bepost_merge_incomplete(main advanced / D1 drifted / optional merged-PR signal) → emit land-b paste for the same slice (do not re-emit land-a). - 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).
- Ambiguity remains fail-closed (
next_regen: human_authorship_required) — never invent a product NEXT. - 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-await for mergeawaiting mergestop 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 3without the fullstop for Tier 3 mergephrase
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/unreadable→ not 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)
- Reuse
check_governance_freshnessfor D1/D2/marker (no re-derivation of GFG rules). - Read default-lane handover text; parse
land-phasefrom NEXT marker; apply §PMHF.4.2 fallback. - Do not call
ghunlessprobe_merged_pr=True(§PMHF.5.3). - Unreadable handover / marker parse failure →
state="unreadable".
§PMHF.5.2 — Resolution order (frozen)
- If config/repo cannot load →
unreadable. - If not initialized (no
version.lock) →not_applicable. - Compute freshness via GFG probe; record
freshness_ok,d1. If freshnessstate == "unreadable"→unreadable(do not mask aspost_merge_incomplete). - Resolve
land_phase(§PMHF.4). - If
land_phase == "land-a"and a matching land queue row exists per §PMHF.3.3 →unreadablewith message tokenland_phase_conflicts_queue_done. Do not treat as complete. - If
land_phaseis None →not_applicable(this probe does not override GFG; status still applies GFG independently). - 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.
- If
- If
land_phase == "land-b":- If freshness not ok OR
d1 == "drifted"→land_b_in_progresswith remediation to finish governance-sync apply + clear land-phase. - Else →
complete.
- If freshness not ok OR
- 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
ghmissing/fails → leaveoptional_pr_merged=None; do not fail open tocomplete.
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: foldland_closeout_okinto the top tier with existing conditions:
… or not governance_freshness_ok or not land_closeout_ok → 2.
Becauseland_a_in_progresshasok=True, waiting for merge does not false-fail status.- Plain
ok statuswithout--exit-codestill exits0.
§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):
- Run
check_land_closeoutwithprobe_merged_pr=True(git regimes). - Set
landed=Trueonly when path checks pass and freshness ok and land_closeout state iscompleteornot_applicable. - If state is
land_a_in_progress,post_merge_incomplete, orland_b_in_progress→landed=False, exit2, 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_incompleteland_closeout: land_b_in_progressland_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):
- Checkout
mainat the push SHA. - Install CLI deps (PyYAML) — same pattern as freeze-review CI template.
- Run
ok governance-sync --dry-run(and optionallyok land-closeout --probe-merged-pr). - 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 onmain. 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 tomain).
- 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-closeoutlocally).
Frozen bans:
- No
git pushtomainfrom this workflow. - No applying governance-sync patches directly onto
mainin CI. - No Cursor-only steps.
- No secrets beyond standard
GITHUB_TOKENfor 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:
- No required config block for the status /
land-closeoutfloor (always-on when initialized). - Existing land NEXT pastes without
land-phase=keep working via §PMHF.4.2 vocabulary fallback. - 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).
- Optional: copy
templates/ci/governance-closeout-github-actions.ymlinto.github/workflows/(Tier 2 confirm-once to enable). Not required for CLI floor. close_ritual.enabled: falseconsumers still get status +ok land-closeout; land-check posture refusal applies only when enabled (unchanged GFG split).- 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. - Blast radius: workflows that claimed “landed” solely from path hashes while NEXT said wait-for
merge will start seeing
land-check/land-closeoutexit2. 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-code → 2 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)
tools/land_closeout/(__init__.py, report +check_land_closeout) per §PMHF.5.cli/commands/land_closeout.py+cli/main.pyregistration forok land-closeout.cli/commands/status.pyadditive JSON/human +--exit-codefold per §PMHF.6.1.tools/close_ritual/land_check.pylanded refusal per §PMHF.6.2.tools/governance_hygiene/next_regen.py(+ patch/engine wiring as needed) land-b emission per §PMHF.3.4; markerland-phase=support per §PMHF.4.- 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.mdif 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 whileok land-closeoutfails
templates/ci/governance-closeout-github-actions.ymlper §PMHF.7.- SPEC §5 additive rows for
ok land-closeout+ statusland_closeoutkey (additive only). - Seven-tier tests under
tests/covering §PMHF.10 (includeland_phase_conflicts_queue_done+ vocabulary false-positive exclusions). - Kit ROADMAP + HANDOVER updated together;
/build-verification-review→passbefore ROADMAP PMHF-b → DONE. - No Cursor-only primary path; no silent main writes; no freeze/BV redesign.
§PMHF.12 — Hard stops (unchanged)
- No kit
mainmerge 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-loopor/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.