Enforce self-propagating canonical handoffs through final controller closure #626
Closed
opened 2026-07-10 11:20:01 -05:00 by jcwalker3
·
4 comments
No Branch/Tag Specified
master
fix/issue-987-native-mcp-bootstrap
feat/issue-985-project-scoped-launcher-identity
fix/issue-983-cross-repo-base-ref
feat/issue-980-stale-worker-retirement
fix/issue-975-client-identity-heartbeat
fix/issue-973-cross-repo-canonical-roots
fix/issue-970-safely-resolve-missing-worktrees
fix/issue-969-native-mcp-bootstrap
feat/issue-664-break-glass-restart
feat/issue-708-mcp-namespace-attachment
feat/issue-665-restart-audit
fix/issue-700-durable-walls
fix/issue-704-prevent-env-workspace-bindings
feat/issue-707-cross-project-boundaries
fix/issue-690-review-profile-switch-guard
fix/issue-953-bootstrap-lock-provenance
feat/issue-949-native-fleet-inventory
fix/issue-943-runtime-context-helpers
fix/issue-945-owning-pr-renewal-evidence
fix/issue-941-scope-guard-bootstrap-wiring
docs/issue-930-remote-mcp-coupling-inventory
fix/issue-892-author-bootstrap-deadlock
fix/issue-686-detect-reject-manual-mcp
fix/issue-672-mcp-config-drift
fix/issue-689-deterministic-mcp-namespace
feat/issue-666-concurrent-mcp-restart-tests
feat/issue-659-maintenance-drain-mode
feat/issue-648-notifications-console
fix/issue-670-direct-master-incident
feat/issue-644-console-recovery
feat/issue-650-providers-insights
feat/issue-669-scoped-component-recovery
docs/issue-668-mcp-ha-rolling-restart
feat/issue-667-console-restart-controls
feat/issue-645-linkage-console
feat/issue-643-request-preview-initiate
fix/issue-897-permission-stale-runtime-classification
feat/issue-641-runtime-session-view
feat/issue-663-restart-classes
feat/issue-661-drain-proof-hard-gate
fix/issue-854-semantic-container-exclusion
issue-640
fix/issue-682-starlette-httpx2
v1.1.0
Labels
Clear labels
allocator
anti-stomp
architecture
bug
chore
codex
concurrency
contamination
control-plane
dashboard
database
design
documentation
enhancement
gitea
glitchtip
important
incident
incident-bridge
integration
jenkins
labels
leases
mcp
mcp-health
mcp-menu
multi-project
mutating
nice-to-have
observability
portability
preflight
protected-branch
queue
read-only
reconnect
recovery
refactor
release
reliability
resumable-review
reviewer
roadmap
safety
security
self-hosted
sentry
stale-runtime
status:blocked
status:in-progress
status:pr-open
status:ready
terminal-lock
testing
tracker
type:bug
type:feature
type:feature
type:guardrail
visibility
workflow
workflow-hardening
workflow-hardening
bug
duplicate
enhancement
help wanted
invalid
question
wontfix
Controller-owned work allocator
Prevent concurrent LLM session stomping
Architecture / structural design
OpenAI Codex client / workflow session surface
Concurrent session safety
Workflow or session contamination incident
MCP control-plane coordination and allocation authority
MCP operational dashboard/queue view
Internal coordination storage (SQLite/Postgres)
Design / investigation, no implementation
Docs / runbooks
New feature or improvement
Gitea MCP workflow
GlitchTip integration
Operational or process incident requiring durable audit trail
Sentry-to-Gitea incident bridging
Integration testing
Jenkins integration
Label taxonomy management
Lease adopt/release/expire lifecycle
MCP server / tooling
MCP namespace and runtime health
MCP menu surface
Work spanning multiple monitoring projects or Gitea repos
Mutating action; requires gating
Observability, metrics, traces, error reporting
Cross-platform / portability
Shared preflight gates before mutation
Protected branch / stable-branch policy concern
Work queue visibility and allocation
Read-only, no mutation
MCP client reconnect/reload recovery path
Recovery paths for stale/foreign leases
Code refactor / restructure
Release / versioning
Reliability / failure handling
Persist and resume prepared review verdicts across sessions
Reviewer workflow tooling
Roadmap / umbrella issue
Safety rails and fail-closed mutation guards
Security / trust boundary
Self-hosted infrastructure integration
Sentry error monitoring integration
Stale backend daemon / runtime-vs-master parity failures
Issue is blocked
Issue is being worked on
Issue has an open pull request
Issue is ready for work
Terminal review lock (#332) path
Tests / test coverage
Issue tracker hygiene / meta
Bug or defect
Feature or enhancement
Feature or enhancement
Safety gate or guardrail
Workflow state visibility for LLMs/operators
Cross-tool workflow
LLM workflow coordination hardening
LLM workflow coordination hardening
Something is not working
This issue or pull request already exists
New feature
Need some help
Something is wrong
More information is needed
This won't be fixed
Milestone
No items
No Milestone
Projects
Clear projects
No projects
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: Scaled-Tech-Consulting/Gitea-Tools#626
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Problem
Current author, reviewer, and merger reports may include a ready-to-paste next prompt, but the workflow does not reliably enforce that each actor:
The gap was demonstrated by the merger handoff produced after review of PR #625 / Issue #601. The prompt included basic merge instructions but did not require:
This means the workflow still depends on a human copying reports into another chat and expanding the next prompt manually.
Desired behavior
Every workflow actor should consume one canonical handoff, perform one authorized workflow role, update Gitea as the durable system of record, and emit the next complete canonical handoff.
The chain should end only when:
Relationship to prior work
This issue does not re-spec the foundational templates already tracked (and largely closed) under:
Those issues define schemas, docs, and partial validators. This issue owns the systemic enforcement gap: self-propagating handoffs across all roles, live-state recovery, mandatory Gitea posting, final-report schema integration that makes the next handoff non-optional, merger →
merged-awaiting-controllertransition, controller accept/reject continuation, and workflow-failure escalation until durable final closure.PR #625 / Issue #601 is a concrete example of the gap, not the sole scope.
Scope
The durable solution should cover the author, reviewer, merger, controller, operator, and reconciliation paths where applicable.
It should define and enforce:
1. Canonical handoff contract
Each handoff must include at least:
2. Live-state recovery
The receiving actor must verify the live Gitea and Git state rather than treating the inherited handoff as authoritative.
The workflow must detect:
3. Role-limited continuation
The receiving actor must perform only the role assigned by the current state.
Examples:
4. Mandatory durable state update
A successful actor session must not end with only a chat report.
It must post or update the canonical Gitea state and thread ledger before completion.
5. Mandatory next handoff
Unless the issue is durably complete, every actor must post a complete ready-to-run prompt for the next actor.
The prompt must be stored in Gitea, not only returned in chat output.
6. Controller completion boundary
A merged PR must not automatically be treated as fully accepted unless the configured workflow authorizes that behavior.
The workflow must represent states such as:
needs-authorneeds-reviewapproved-awaiting-mergemerged-awaiting-controllerblockedcompleteThe controller must be able to:
7. Workflow-failure escalation
Any tooling or workflow failure discovered while processing a work item must be captured in durable issue work.
The current work item should contain:
The actor should not silently fold an unrelated workflow defect into the active feature issue.
8. Validation before posting
Canonical handoff comments should be schema-validated before Gitea accepts them.
Missing or ambiguous fields should fail closed with actionable feedback.
9. Final-report integration
Author, reviewer, merger, controller, operator, and reconciler final-report schemas should generate or require the canonical next handoff consistently.
The next prompt should not be an optional prose section.
Acceptance criteria
A canonical schema exists for cross-role handoffs.
Applicable workflow final-report schemas require that handoff.
A validator rejects incomplete handoffs.
Successful actor workflows post the handoff into Gitea.
The receiving actor can recover the task using only:
No outside chat history is required.
Head changes invalidate stale review or merge handoffs.
Merge success transitions to the configured controller state.
Controller acceptance or rejection generates the appropriate final or next state.
Workflow failures produce a separate durable issue reference.
Completed workflows terminate without generating an unnecessary next prompt.
Tests cover at least:
Non-goals
Evidence / example
Use PR #625 / Issue #601 as a concrete example of the gap:
Describe this as an example, not as the sole scope.
Issue claim heartbeat
[THREAD STATE LEDGER]
What is true now
master.ddc9b97d401a3102f4088abc27cbe1be1795f3a0, parented on1d11cbab0fdc529859bdace2bd01e20da22ff449.What changed
recovery_mode: unpublished_claim, prior pid 2100 dead, ancestry proven against recorded base1d11cbab);feat/issue-626-self-propagating-handoffscreated at commitddc9b97d401a3102f4088abc27cbe1be1795f3a0through native MCPgitea_commit_files;master;status:pr-openby the PR-creation transition;b2977a35already existed inbranches/issue-626-self-propagating-handoffs; the published tree4df467f5746be4f6c86a9d229250b7eefd5354d0is byte-identical to it.What is blocked
Who/what acts next
jcwalker3, in the reviewer namespace).ddc9b97d401a3102f4088abc27cbe1be1795f3a0and post a verdict.ddc9b97d; do not rewrite, force-push, or rebase the branch; do not treat the twelve pre-existing master test failures listed below as regressions from this branch.Canonical Issue State
STATE: pr-open-awaiting-independent-review
WHO_IS_NEXT: reviewer
NEXT_ACTION: Perform an independent native reviewer-namespace review of PR #779 pinned to head
ddc9b97d40and post a verdict.NEXT_PROMPT: Act as the independent reviewer for Scaled-Tech-Consulting/Gitea-Tools on remote prgs. Review PR #779, which closes issue #626 and adds the self-propagating canonical handoff protocol. Bind a reviewer namespace and profile whose identity is not jcwalker3, verify runtime parity and control-checkout cleanliness, then pin the live PR head, which was
ddc9b97d40against base master at1d11cbab0fwhen this handoff was written, and re-derive that head from live state before deciding. Examine the new module self_propagating_handoff.py, its wiring into final_report_validator.py as rule shared.self_propagating_handoff across nine task kinds, the schema document skills/llm-project-workflow/schemas/self-propagating-handoff.md, and the five final-report schema updates. Check each acceptance criterion of issue #626, including the nine enforcement areas, the fourteen live-state detection kinds, the four controller closure proofs, the workflow-failure escalation fields with duplicate handling, and terminal closure that emits no further prompt. Re-run pytest tests/test_self_propagating_handoff.py and the full suite from a reviewer worktree under branches/, and compare any failures against a clean checkout at base1d11cbabbefore attributing them to this branch. Post a native verdict through the reviewer namespace, then leave the next canonical handoff on issue #626. Everything you need is in this issue thread, PR #779, the workflow documentation, and live repository state.WHAT_HAPPENED: An earlier author session of this loop implemented issue #626 and committed it locally as b2977a35, then exited before publishing. This fire proved ownership through canonical dead-session recovery rather than re-implementing, re-ran the validation evidence, published the branch through native MCP, and opened PR #779.
WHY: Issue #626 owns the systemic enforcement gap left by #494 through #507: nothing forced the handoff chain itself. The change adds the canonical cross-role handoff contract, a fail-closed validator, live-state recovery, role-limited continuation, mandatory durable posting into Gitea, the post-merge controller boundary, controller accept and reject continuation, and workflow-failure escalation into separate durable issues.
ISSUE: 626
HEAD_SHA:
ddc9b97d40REVIEW_STATUS: No verdict exists on PR #779; the PR awaits its first independent review.
MERGE_READY: Not evaluated by this session. Merge authority belongs to the merger role and is out of author scope.
RELATED_PRS: #779
BLOCKERS: none
VALIDATION: pytest tests/test_self_propagating_handoff.py returned 53 passed. The full suite on this branch returned 4009 passed, 12 failed, 6 skipped, 493 subtests passed in 672s. All twelve failures reproduce identically on a clean checkout at the exact base SHA
1d11cbab0fin worktree branches/baseline-master-issue-626, so they are pre-existing on master and are not caused by this branch: six in tests/test_commit_payloads.py, two in tests/test_issue_702_review_findings_f1_f6.py, and one each in tests/test_mcp_server.py TestPreflightVerification, tests/test_post_merge_moot_lease.py TestAcquireToolRefusesMergedPR, tests/test_reconciler_supersession_close.py TestReconcilerSupersessionMcpTool, and tests/test_webui_ci_gate.py TestCiRunnerScript. git diff --check over the branch range reported no whitespace defects.LAST_UPDATED_BY: jcwalker3 / prgs-author (LLM_LOCK_ID claude-author-loop-prod-v1, LLM_EXECUTION_ID claude-author-loop-prod-v1-20260721T071305Z-pid94743-0bfff856)
Canonical Handoff
Canonical Issue State
STATE: merged-awaiting-controller
WHO_IS_NEXT: controller
NEXT_ACTION: Verify acceptance criteria, verify cleanup, verify final state and close Issue #626 through sanctioned controller workflow
NEXT_PROMPT:
WHAT_HAPPENED: PR #779 merged under merger profile prgs-merger at head
ddc9b97d40with merge commitdf3167488c.WHY: Approved review 491 was verified valid and non-stale at current head; namespace health and parity verified; lease acquired.
RELATED_PRS: #779
BLOCKERS: none
VALIDATION: PR successfully merged; local git fetch verified commit
df3167488cis present and is master branch head.LAST_UPDATED_BY: sysadmin / prgs-merger (LLM_LOCK_ID gemini-merger-loop)
Canonical Handoff
[THREAD STATE LEDGER]
What is true now
df3167488c5451f802549b40463ad59cbaad6109.ddc9b97d401a3102f4088abc27cbe1be1795f3a0; the merge commit's tree4df467f5746be4f6c86a9d229250b7eefd5354d0is byte-identical to that head's tree, so nothing drifted between review and landing.sysadmin/prgs-revieweris an APPROVED review posted to Gitea at headddc9b97d401a3102f4088abc27cbe1be1795f3a0, withdismissed: false,stale: false,quarantined: false,approval_at_current_head: true. Merge result: merge performed at 2026-07-21T12:53:50-05:00 by profileprgs-merger.df3167488c5451f802549b40463ad59cbaad6109(clean control checkout, runtime in parity) and re-ran the focused suite at the merged tree with the result 53 passed.What changed
feat/issue-626-self-propagating-handoffsdeleted through nativegitea_cleanup_merged_pr_branch, post-delete readbackverified_absent: true,branch_present: false;Local-only changes: four worktrees belonging to this work item were removed after a captured pre-removal snapshot proved each one clean —
branches/review-pr-779-ddc9b97(detachedddc9b97),branches/review-418(detachedddc9b97),branches/baseline-master-issue-626(detached1d11cbab) andbranches/issue-626-self-propagating-handoffs; the local branchfeat/issue-626-self-propagating-handoffsatb2977a35bffefbe6a58a977d3fe16aac27833a18was deleted only after proving its tree equals the landed tree4df467f5746be4f6c86a9d229250b7eefd5354d0. Cleanup integrity reconciled 4 initial / 4 removed / 0 preserved-missing / 0 orphaned, withintegrity_passed: true. Every other worktree was left untouched.What is blocked
status:pr-open. Theprgs-reconcilerprofile holds no issue-label permission, so the stale label is reported here instead of being edited through an unauthorized path.Who/what acts next
Canonical Issue State
STATE: accepted
WHO_IS_NEXT: user
NEXT_ACTION:
The workflow chain for Issue #626 is terminated at controller acceptance; no further workflow action is authorized on this issue.
NEXT_PROMPT:
WHAT_HAPPENED: The controller verified the merge, the acceptance criteria, the durable evidence chain and the required cleanup for Issue #626, then recorded final acceptance. Issue #626 was closed by the sanctioned merge of PR #779, whose body declares
Closes #626.WHY: Every acceptance criterion of Issue #626 is satisfied in the merged tree, the reviewed head landed without drift, the required handoffs are durable on this thread, and the sanctioned post-merge cleanup completed with proof.
ISSUE: 626
HEAD_SHA:
ddc9b97d40RELATED_PRS: #779
BLOCKERS: none
VALIDATION: merge parents
1d11cbab0fdc529859bdace2bd01e20da22ff449andddc9b97d401a3102f4088abc27cbe1be1795f3a0; merge tree4df467f5746be4f6c86a9d229250b7eefd5354d0equals the reviewed head tree;pytest tests/test_self_propagating_handoff.pyat the merged tree returned 53 passed; ruleshared.self_propagating_handoffregistered for nine task kinds; schema document and five final-report schemas present in the merged tree.NATIVE_REVIEW_PROOF: transport=native_mcp; namespace=gitea-reviewer; profile=prgs-reviewer; identity=sysadmin; tool=gitea_submit_pr_review; review_id=491; head=ddc9b97d401a3102f4088abc27cbe1be1795f3a0
LAST_UPDATED_BY: sysadmin / prgs-reconciler (controller closure) / 2026-07-21
Controller Issue Acceptance
STATE: accepted
WHO_IS_NEXT: user
NEXT_ACTION:
Record no further workflow action for Issue #626; the chain terminates at this controller acceptance.
NEXT_PROMPT:
ISSUE: #626
MERGED_PR: #779
MERGE_COMMIT:
df3167488cACCEPTANCE_CRITERIA_CHECKED:
skills/llm-project-workflow/schemas/self-propagating-handoff.mdin the merged tree.skills/llm-project-workflow/SKILL.md.assess_self_propagating_handofffails closed on missing or placeholder fields; wired as ruleshared.self_propagating_handofffor review_pr, merge_pr, reconcile_already_landed, author_issue, work_issue, issue_filing, inventory, issue_selection and controller_close.assess_durable_state_updaterejects a chat-only report; comments 13568, 13589 and this comment are the durable chain on this thread.assess_thread_recoverabilityrejects prompts that lean on outside chat history; this controller session recovered the task from this thread with no outside chat context.assess_handoff_live_statecovers all fourteen detection kinds includingchanged_pr_headandstale_approval.assess_merge_completion_transitionmoves a merged PR tomerged-awaiting-controller, which is exactly the state comment 13589 recorded.assess_controller_decisionhonors accept only with all four closure proofs and routes request_tests, request_proof, request_corrections, reopen and return_to_actor.assess_workflow_failure_escalationrequires classification, linked_issue, temporary_impact, next_valid_actor and recovery_prompt per distinct defect and reuses an existing issue for a known signature.completemust carry no NEXT_ACTION and no NEXT_PROMPT, as the canonical handoff at the top of this comment demonstrates.tests/test_self_propagating_handoff.py, 53 passed at the merged tree.VALIDATION_REVIEWED: Reviewer 491 evidence (focused 53 passed; full suite 4010 passed / 11 failed / 6 skipped, with the eleven failures reproduced identically on a clean checkout at base
1d11cbab0fdc529859bdace2bd01e20da22ff449, so they are pre-existing on master and are not caused by this work) plus the controller's own re-run ofpytest tests/test_self_propagating_handoff.pyat the merged tree, which returned 53 passed.CONTROLLER_DECISION: accepted
WHY: All acceptance criteria are satisfied in the merged tree, the landed tree is identical to the independently reviewed head, the durable handoff chain is present on this thread, and the sanctioned post-merge cleanup completed with proof.
MISSING_WORK: none
FOLLOW_UP_ISSUES: none
BLOCKERS: none
CLEANUP_PERFORMED: remote branch
feat/issue-626-self-propagating-handoffsdeleted and verified absent; four #626/#779 worktrees removed; local branch deleted after tree-parity proof; no active workflow lease remained on Issue #626 or PR #779.LAST_UPDATED_BY: sysadmin / prgs-reconciler (controller closure) / 2026-07-21