Make merger lease-proof recovery explicit and non-bypassable #535

Closed
opened 2026-07-08 04:18:46 -05:00 by jcwalker3 · 2 comments
Owner

Problem:
During the merges of PR #493 and PR #421, the final handoff says the PRs were merged “using manually seeded lease proof.” That phrase is ambiguous and dangerous. It is unclear whether the merge gate was legitimately satisfied through a recovery/adoption path or whether a script manually injected state to bypass the normal lease gate.

Risk:
If LLM sessions can manually seed lease proof without a strict recovery protocol, merge gates may become performative. Future sessions could merge with stale, missing, or fabricated lease state while still producing a plausible handoff.

Required behavior:

  1. Any merger lease-proof recovery must be an explicit MCP tool path, not an ad hoc script mutation.
  2. The recovery path must record:
    • PR number
    • session ID
    • original lease/comment ID
    • authenticated identity
    • expected head SHA
    • reason recovery was needed
  3. Recovery must fail unless normal merge gates still pass:
    • not author
    • approved at current head
    • no blocking REQUEST_CHANGES
    • expected head SHA matches
    • PR open and mergeable
  4. Handoffs must distinguish:
    • normal merge lease
    • adopted/recovered lease
    • post-merge moot lease
    • blocked/stale lease
  5. The merge tool must reject unverifiable manually seeded proof.

Acceptance criteria:

  • Add tests proving ad hoc/manual seeded lease proof is rejected.
  • Add tests for a legitimate lease adoption/recovery path.
  • Add tests that recovered lease proof still requires approval-at-head and expected-head checks.
  • Add canonical merge report fields for lease proof source and recovery reason.
  • Add controller audit checks for any merge report containing “manual,” “seeded,” or “injected” lease proof.
Problem: During the merges of PR #493 and PR #421, the final handoff says the PRs were merged “using manually seeded lease proof.” That phrase is ambiguous and dangerous. It is unclear whether the merge gate was legitimately satisfied through a recovery/adoption path or whether a script manually injected state to bypass the normal lease gate. Risk: If LLM sessions can manually seed lease proof without a strict recovery protocol, merge gates may become performative. Future sessions could merge with stale, missing, or fabricated lease state while still producing a plausible handoff. Required behavior: 1. Any merger lease-proof recovery must be an explicit MCP tool path, not an ad hoc script mutation. 2. The recovery path must record: - PR number - session ID - original lease/comment ID - authenticated identity - expected head SHA - reason recovery was needed 3. Recovery must fail unless normal merge gates still pass: - not author - approved at current head - no blocking REQUEST_CHANGES - expected head SHA matches - PR open and mergeable 4. Handoffs must distinguish: - normal merge lease - adopted/recovered lease - post-merge moot lease - blocked/stale lease 5. The merge tool must reject unverifiable manually seeded proof. Acceptance criteria: - Add tests proving ad hoc/manual seeded lease proof is rejected. - Add tests for a legitimate lease adoption/recovery path. - Add tests that recovered lease proof still requires approval-at-head and expected-head checks. - Add canonical merge report fields for lease proof source and recovery reason. - Add controller audit checks for any merge report containing “manual,” “seeded,” or “injected” lease proof.
Author
Owner

Canonical Issue State

STATE: partially-satisfied-by-#536; remains open
WHO_IS_NEXT: author
NEXT_ACTION: implement remaining #535 acceptance gaps (report fields + controller audit), then re-request close
NEXT_PROMPT:

Use prgs-author. On Issue #535, implement remaining gaps only:
1) gitea_merge_pr success/fail reports include lease_proof_source + recovery_reason/adoption_reason when an adopted lease was used;
2) final_report_validator controller audit rule rejecting merge/handoff reports that claim manual/seeded/injected lease proof without sanctioned MCP adoption;
3) tests for both. Keep scope tight; do not rework adoption core from #536.

WHAT_HAPPENED: Audited #535 against live master after #536 / PR #538 landed.
WHY: #536 closed the noncanonical manual _SESSION_LEASE seeding path with gitea_adopt_merger_pr_lease, but #535 acceptance is not fully covered.
RELATED_PRS: #538 (merged cfce823; closes #536 only)
BLOCKERS: none for analysis; implementation still required for listed residual gaps
VALIDATION:

  • gitea_view_issue #536: closed
  • gitea_view_pr #538: closed/merged at cfce823dd7343bbafecbff82d807a27884c60b6c; ancestor of prgs/master c738e5b
  • pytest tests/test_merger_lease_adoption.py tests/test_reviewer_pr_lease.py → 21 passed on master worktree
    LAST_UPDATED_BY: jcwalker3 (prgs-author)

Evidence matrix (#535 requirements vs master)

#535 requirement Status Evidence
Explicit MCP recovery path (not ad hoc script) DONE gitea_adopt_merger_pr_lease + merger_lease_adoption.py
Record PR, session, original comment id, identity, expected head, recovery reason DONE adoption body + lease_provenance / adoption_reason: merger-handoff-approved-head
Fail without approval-at-head / head pin / open PR DONE assess_adopt_merger_lease + adopt tool feedback gate
Merge rejects bare manual _SESSION_LEASE seeding DONE assess_mutation_lease_gate + test_manual_session_seed_rejected_by_mutation_gate
Distinguish normal / adopted / post-merge-moot / blocked MOSTLY DONE phases claimed/adopted/released + post-merge-moot cleanup tool
Canonical merge report fields lease_proof_source + recovery reason GAP gitea_merge_pr returns merge_capability_source (profile/config only); no lease_proof_source / adoption_reason on merge result
Controller audit for handoff text containing manual/seeded/injected lease proof GAP final_report_validator has lock-seed rule only (shared.manual_lock_pr_override), not merger lease-proof language
Explicit adopt-time self-author + mergeable gates PARTIAL self-merge + mergeable enforced on gitea_merge_pr eligibility; adopt relies mainly on approval-at-head

Residual work (keep #535 open)

  1. Surface lease_proof_source + recovery/adoption reason on merge reports when lease gate used adoption provenance.
  2. Add final-report/controller audit rule for manual/seeded/injected lease proof claims without sanctioned MCP path.
  3. Tests covering (1) and (2).

Not closing #535. Core runtime recovery is landed via #536/#538; remaining acceptance is report/audit completeness.

## Canonical Issue State STATE: partially-satisfied-by-#536; remains open WHO_IS_NEXT: author NEXT_ACTION: implement remaining #535 acceptance gaps (report fields + controller audit), then re-request close NEXT_PROMPT: ```text Use prgs-author. On Issue #535, implement remaining gaps only: 1) gitea_merge_pr success/fail reports include lease_proof_source + recovery_reason/adoption_reason when an adopted lease was used; 2) final_report_validator controller audit rule rejecting merge/handoff reports that claim manual/seeded/injected lease proof without sanctioned MCP adoption; 3) tests for both. Keep scope tight; do not rework adoption core from #536. ``` WHAT_HAPPENED: Audited #535 against live master after #536 / PR #538 landed. WHY: #536 closed the noncanonical manual _SESSION_LEASE seeding path with gitea_adopt_merger_pr_lease, but #535 acceptance is not fully covered. RELATED_PRS: #538 (merged cfce823; closes #536 only) BLOCKERS: none for analysis; implementation still required for listed residual gaps VALIDATION: - gitea_view_issue #536: closed - gitea_view_pr #538: closed/merged at cfce823dd7343bbafecbff82d807a27884c60b6c; ancestor of prgs/master c738e5b - pytest tests/test_merger_lease_adoption.py tests/test_reviewer_pr_lease.py → 21 passed on master worktree LAST_UPDATED_BY: jcwalker3 (prgs-author) ### Evidence matrix (#535 requirements vs master) | #535 requirement | Status | Evidence | |---|---|---| | Explicit MCP recovery path (not ad hoc script) | **DONE** | `gitea_adopt_merger_pr_lease` + `merger_lease_adoption.py` | | Record PR, session, original comment id, identity, expected head, recovery reason | **DONE** | adoption body + `lease_provenance` / `adoption_reason: merger-handoff-approved-head` | | Fail without approval-at-head / head pin / open PR | **DONE** | `assess_adopt_merger_lease` + adopt tool feedback gate | | Merge rejects bare manual `_SESSION_LEASE` seeding | **DONE** | `assess_mutation_lease_gate` + `test_manual_session_seed_rejected_by_mutation_gate` | | Distinguish normal / adopted / post-merge-moot / blocked | **MOSTLY DONE** | phases claimed/adopted/released + post-merge-moot cleanup tool | | Canonical **merge report** fields `lease_proof_source` + recovery reason | **GAP** | `gitea_merge_pr` returns `merge_capability_source` (profile/config only); no lease_proof_source / adoption_reason on merge result | | Controller audit for handoff text containing manual/seeded/injected lease proof | **GAP** | `final_report_validator` has lock-seed rule only (`shared.manual_lock_pr_override`), not merger lease-proof language | | Explicit adopt-time self-author + mergeable gates | **PARTIAL** | self-merge + mergeable enforced on `gitea_merge_pr` eligibility; adopt relies mainly on approval-at-head | ### Residual work (keep #535 open) 1. Surface `lease_proof_source` + recovery/adoption reason on merge reports when lease gate used adoption provenance. 2. Add final-report/controller audit rule for manual/seeded/injected lease proof claims without sanctioned MCP path. 3. Tests covering (1) and (2). **Not closing #535.** Core runtime recovery is landed via #536/#538; remaining acceptance is report/audit completeness.
jcwalker3 added the status:in-progress label 2026-07-09 11:56:59 -05:00
Author
Owner

Issue claim heartbeat

<!-- gitea-issue-claim-heartbeat:v1 --> **Issue claim heartbeat** - kind: claim - issue: #535 - branch: feat/issue-535-lease-proof-report - phase: claimed - profile: prgs-author - pr: none - blocker: none - next_action: create worktree and begin implementation
jcwalker3 added status:pr-open and removed status:in-progress labels 2026-07-09 12:02:57 -05:00
sysadmin removed the status:pr-open label 2026-07-09 13:24:18 -05:00
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Scaled-Tech-Consulting/Gitea-Tools#535