Merge remote-tracking branch 'prgs/master' into issue-552-blocked-diagnose
# Conflicts: # skills/llm-project-workflow/SKILL.md
This commit is contained in:
@@ -0,0 +1,190 @@
|
||||
# Bootstrap Review Path for Self-Hosted MCP Workflow Fixes (#557)
|
||||
|
||||
## Purpose
|
||||
|
||||
Gitea-Tools MCP workflow fixes can create a **bootstrap deadlock**: the live
|
||||
MCP daemons still run the broken code from `master`, so canonical reviewer /
|
||||
merger tools cannot complete the review that would land the fix.
|
||||
|
||||
This document defines a **narrow, controller-authorized bootstrap path** so
|
||||
such fixes can land without weakening normal review/merge gates.
|
||||
|
||||
It is **not** a general bypass. Normal PRs must still use the full
|
||||
reviewer → merger MCP workflow.
|
||||
|
||||
## When this path applies
|
||||
|
||||
All of the following must be true:
|
||||
|
||||
1. The PR changes **Gitea-Tools MCP workflow / preflight / lease / gate** code
|
||||
that the live daemon must load to review itself (self-hosted control plane).
|
||||
2. Canonical review or merge tools **fail closed** because of that defect
|
||||
(documented tool errors, not “inconvenience”).
|
||||
3. A **controller** records an explicit bootstrap authorization on the PR or
|
||||
linked issue (see below).
|
||||
4. The PR source is clean, testable, and free of unrelated scope.
|
||||
|
||||
Example (historical): PR #553 / Issue #546 (reviewer preflight capability/lease
|
||||
deadlock). Live daemons on unpatched `master` could not complete canonical
|
||||
review of the fix PR.
|
||||
|
||||
## Durable authorization (required)
|
||||
|
||||
**No manual remote merge, force-merge, or API merge of a bootstrap PR is
|
||||
allowed** unless a controller has posted a durable authorization record on
|
||||
Gitea.
|
||||
|
||||
### Authorization record (issue or PR comment)
|
||||
|
||||
The controller comment **must** include a machine-readable marker and the
|
||||
fields below:
|
||||
|
||||
```text
|
||||
## BOOTSTRAP REVIEW AUTHORIZATION (#557)
|
||||
|
||||
Status: APPROVED
|
||||
PR: <number>
|
||||
Issue: <number>
|
||||
Controller: <gitea username>
|
||||
Reason: live MCP runtime cannot canonically review this self-hosted workflow fix
|
||||
Scope: narrow bootstrap only — does not weaken normal PR gates
|
||||
|
||||
Validation evidence:
|
||||
- git diff --check: clean
|
||||
- targeted pytest: <command> → pass
|
||||
- full suite attribution (if non-zero): baseline compared to prgs/master
|
||||
|
||||
Duplicate-PR audit: <none | list and disposition>
|
||||
Mutation ledger audit: <summary or path to proof>
|
||||
Contamination audit: <clean | list contaminated comment/lease IDs and disposition>
|
||||
|
||||
Allowed verification actions used: <list>
|
||||
Forbidden actions NOT used: root checkout edits; raw curl mutation; direct
|
||||
module import of gitea_mcp_server for mutations; in-memory gate restoration
|
||||
|
||||
Post-land plan:
|
||||
- restart MCP daemons for author/reviewer/merger/reconciler profiles
|
||||
- re-verify with canonical tools (see Post-bootstrap steps)
|
||||
```
|
||||
|
||||
Without this record, bootstrap merge is **forbidden**. Agents must stop with
|
||||
`BLOCKED + DIAGNOSE` rather than improvise a merge.
|
||||
|
||||
## Review gates and proof (still required)
|
||||
|
||||
Bootstrap does **not** skip technical review. It only allows verification and
|
||||
landing when the **live MCP mutation path** cannot complete the review.
|
||||
|
||||
Before authorization, the controller (or a delegated read-only verifier in an
|
||||
isolated worktree) must have:
|
||||
|
||||
| Gate | Requirement |
|
||||
|------|-------------|
|
||||
| Diff hygiene | `git diff --check` clean on the PR tip vs `prgs/master` |
|
||||
| Tests | Targeted tests for the fix pass; full suite either green or failures attributed to baseline `prgs/master` |
|
||||
| Duplicate PR | Open-PR inventory shows no competing open PR for the same issue (or supersession is documented) |
|
||||
| Mutation ledger | Any claimed mutations are ledger-consistent; no silent root edits |
|
||||
| Contamination audit | PR/issue comments and leases classified as clean vs workflow-contaminated |
|
||||
| Scope | Diff limited to the bootstrap issue; no drive-by refactors |
|
||||
|
||||
### Contamination audit (comments / leases)
|
||||
|
||||
Comments or leases created via **raw curl**, **direct Python import of MCP
|
||||
modules**, or **token extraction** are **workflow-contaminated**. They must be
|
||||
listed and must **not** be treated as canonical review proof.
|
||||
|
||||
Only comments posted via **sanctioned MCP reviewer tools** (after the fix is
|
||||
landed and daemons restarted, or during a clean path that did not bypass gates)
|
||||
count as canonical review state.
|
||||
|
||||
Historical example on PR #553:
|
||||
|
||||
| Comment | Disposition |
|
||||
|---------|-------------|
|
||||
| #7247 test / raw API | contaminated |
|
||||
| #7251 lease metadata / raw API | contaminated |
|
||||
| #7252 lease metadata / direct import | contaminated |
|
||||
| #7265 lease metadata / MCP reviewer tools | workflow-clean |
|
||||
|
||||
## Allowed verification actions
|
||||
|
||||
These may run **outside** the broken live mutation path to establish facts:
|
||||
|
||||
- Read-only MCP tools (`gitea_view_pr`, `gitea_list_prs`, `gitea_whoami`,
|
||||
`gitea_get_profile`, inventory, eligibility **reads**).
|
||||
- Isolated `branches/` worktree checkout of the PR head (never root).
|
||||
- `git fetch`, `git log`, `git diff`, `git merge-tree` (read-only analysis).
|
||||
- Targeted `pytest` / `py_compile` inside that worktree.
|
||||
- Controller posting of the bootstrap authorization comment via a healthy
|
||||
MCP profile **if available**; if comment mutation is also deadlocked, a
|
||||
**human operator** posts the authorization in the Gitea UI (still durable on
|
||||
the thread).
|
||||
|
||||
## Forbidden actions (always)
|
||||
|
||||
Even under bootstrap:
|
||||
|
||||
- Editing or committing in the **project root / control checkout**.
|
||||
- Treating root as a worktree for implementation or review mutations.
|
||||
- Raw `curl` / REST mutation with extracted tokens as a normal workflow.
|
||||
- `import gitea_mcp_server` (or sibling modules) from a shell to call mutation
|
||||
helpers and bypass preflight.
|
||||
- In-memory restoration of capability / lease / decision state to “finish”
|
||||
a blocked chain.
|
||||
- Force-push, history rewrite, or deleting evidence comments.
|
||||
- Weakening normal gates in code “temporarily” without a tracked issue/PR.
|
||||
- Self-review or self-merge by the PR author identity.
|
||||
|
||||
## Landing procedure (after APPROVED authorization)
|
||||
|
||||
1. Confirm the authorization record is present and complete on the PR or issue.
|
||||
2. Merge **only** with an independent merger identity when possible.
|
||||
- Preferred: restart/replace the MCP merger daemon with a build that includes
|
||||
the fix (or a one-shot process started from the PR worktree binary) so
|
||||
`gitea_merge_pr` can run under normal gates.
|
||||
- If the live merger daemon still cannot load the fix, a **human operator**
|
||||
may merge via the Gitea UI **only** after the authorization record exists.
|
||||
3. Never merge from contaminated proof alone.
|
||||
|
||||
## Post-bootstrap steps
|
||||
|
||||
### 1. Restart MCP daemons
|
||||
|
||||
After the fix lands on `prgs/master`:
|
||||
|
||||
1. Stop author / reviewer / merger / reconciler MCP server processes for this
|
||||
repo (IDE MCP pool + any long-lived terminals).
|
||||
2. Confirm no stale PID still serves the old code.
|
||||
3. Restart each profile so it loads the updated `master` tree (or installed
|
||||
package path).
|
||||
4. Call `gitea_whoami` / `gitea_get_profile` on each namespace and record
|
||||
profile name + identity.
|
||||
|
||||
### 2. Re-verify with canonical tools
|
||||
|
||||
Example pattern after PR #553-class fixes (lease release / #550-style follow-up):
|
||||
|
||||
1. From a **reviewer** MCP session: acquire/release or inspect the relevant
|
||||
lease with canonical tools only.
|
||||
2. Confirm no direct-import or raw-API path is required.
|
||||
3. Post a short controller or reconciler note: bootstrap complete; normal gates
|
||||
restored.
|
||||
|
||||
If verification still requires a bypass, open a new issue — do **not** extend
|
||||
this bootstrap authorization silently.
|
||||
|
||||
## Explicit non-goals
|
||||
|
||||
- This path does **not** authorize skipping tests, duplicate audits, or
|
||||
contamination audits.
|
||||
- This path does **not** authorize root checkout implementation work.
|
||||
- This path does **not** replace BLOCKED + DIAGNOSE when a non-bootstrap
|
||||
failure occurs (#552).
|
||||
- This path does **not** grant permanent “operator exception” culture.
|
||||
|
||||
## Related
|
||||
|
||||
- Root checkout policy: `docs/llm-workflow-runbooks.md` (Global LLM Worktree Rule, #475)
|
||||
- BLOCKED + DIAGNOSE: issue #552 / skill workflows
|
||||
- Reviewer lease / preflight deadlock class: issues #546, #548, #550
|
||||
- Durable session proofs across daemon pools: issue #559
|
||||
@@ -0,0 +1,52 @@
|
||||
# Controller Issue-Acceptance Gate
|
||||
|
||||
A merged PR does not automatically prove an issue is fully satisfied. After
|
||||
merge, a controller must audit the linked issue against its acceptance criteria
|
||||
and post a durable handoff before the issue is treated as complete.
|
||||
|
||||
## Workflow position
|
||||
|
||||
1. Author implements the issue and opens a PR.
|
||||
2. Reviewer reviews the PR.
|
||||
3. Merger merges the approved PR.
|
||||
4. **Controller performs issue-acceptance audit.**
|
||||
5. Controller posts a `## Controller Issue Acceptance` comment with either:
|
||||
- `STATE: accepted` and checked criteria, or
|
||||
- a rejection path (`more-work-required`, `needs-tests`, `needs-docs`, etc.)
|
||||
with `MISSING_WORK` and a paste-ready `NEXT_PROMPT`.
|
||||
|
||||
Gitea may auto-close an issue via `Closes #N` in the PR body. That closure is
|
||||
merge mechanics only. Controller acceptance is still required before any final
|
||||
report or queue controller treats the issue as complete.
|
||||
|
||||
## Template
|
||||
|
||||
Use `issue_acceptance_gate.render_controller_acceptance_template()` or the
|
||||
copy in
|
||||
[`skills/llm-project-workflow/templates/controller-issue-acceptance.md`](../skills/llm-project-workflow/templates/controller-issue-acceptance.md).
|
||||
|
||||
## Final-report rules
|
||||
|
||||
Final reports must not claim `issue complete` solely because a PR merged.
|
||||
Either:
|
||||
|
||||
- include a valid `## Controller Issue Acceptance` block with
|
||||
`STATE: accepted`, or
|
||||
- explicitly state `controller acceptance pending` and identify the controller
|
||||
as the next actor.
|
||||
|
||||
`final_report_validator` enforces this through
|
||||
`issue_acceptance_gate.validate_final_report_issue_acceptance()`.
|
||||
|
||||
## Role boundaries
|
||||
|
||||
- Authors must not mark their own issues accepted.
|
||||
- Reviewers must not mark issue acceptance unless acting under controller
|
||||
capability.
|
||||
- Mergers merge PRs; they do not substitute for controller acceptance.
|
||||
|
||||
## Related
|
||||
|
||||
- #495 — canonical next-action comment templates
|
||||
- #496 — fail-closed canonical comment validation before posting
|
||||
- #303 — controller handoff schema for reconciliation workflows
|
||||
@@ -410,6 +410,28 @@ The guard blocks when the **control checkout** (repository root) is:
|
||||
`branches/...` directories are disposable role worktrees; the root checkout is
|
||||
the stable orchestration surface only.
|
||||
|
||||
## Bootstrap Review Path for self-hosted MCP fixes (#557)
|
||||
|
||||
When a PR fixes Gitea-Tools MCP workflow code that the **live daemon** still
|
||||
runs from broken `master`, canonical review can deadlock on itself.
|
||||
|
||||
Do **not** improvise raw API, direct imports, root edits, or gate bypasses.
|
||||
|
||||
Use the narrow controller-authorized path documented in:
|
||||
|
||||
- [`docs/bootstrap-review-path.md`](bootstrap-review-path.md)
|
||||
|
||||
Hard rules:
|
||||
|
||||
- No merge without a durable `BOOTSTRAP REVIEW AUTHORIZATION (#557)` record on
|
||||
the PR or linked issue.
|
||||
- Validation, duplicate-PR, mutation-ledger, and contamination audits remain
|
||||
mandatory.
|
||||
- Root checkout stays read-only orchestration only; verification runs in
|
||||
`branches/` worktrees.
|
||||
- After land: restart MCP daemons and re-verify with canonical tools only.
|
||||
- This never weakens normal reviewer/merger gates for ordinary PRs.
|
||||
|
||||
## Shell Spawn Hard-Stop Rule
|
||||
|
||||
Symptom: a shell tool call returns `exit_code: -1` with empty stdout/stderr.
|
||||
@@ -718,6 +740,27 @@ merger handoff.
|
||||
- **Prompt (normal):** `After verifying master contains the merge of PR #N using post-merge file-presence verification, close issue #M and delete the merged branch. Include verification details in the report.`
|
||||
- **Prompt (reconcile):** `Reconcile closed-not-merged PR #N by verifying if its content landed on master.`
|
||||
|
||||
### Post-merge merged cleanup ownership (#523)
|
||||
|
||||
Post-merge **local worktree / remote branch cleanup** is **reconciler** work, not
|
||||
author work. Do not switch from `prgs-reconciler` to `prgs-author` only to run
|
||||
`gitea_reconcile_merged_cleanups`.
|
||||
|
||||
- **Profile:** `prgs-reconciler` (task `reconcile_merged_cleanups` /
|
||||
`reconciliation_cleanup`).
|
||||
- **Namespace:** reconciler MCP server; stable control checkout is allowed for
|
||||
this role (branches-only author guard does not apply).
|
||||
- **Steps:**
|
||||
1. `gitea_whoami` + `gitea_resolve_task_capability(task="reconcile_merged_cleanups")`.
|
||||
2. Dry-run first: `gitea_reconcile_merged_cleanups(dry_run=True)`.
|
||||
3. Execute only after audit/authorization gates when remote branch delete or
|
||||
worktree removal is required (`dry_run=False`, `execute_confirmed=True`,
|
||||
and `gitea.branch.delete` when deleting remotes).
|
||||
- **Fail closed:** unmerged/open heads, mismatched worktrees, and non-merged
|
||||
closed PRs must not be cleaned.
|
||||
- **Reports:** label cleanup actions as reconciler cleanup (not author mutation).
|
||||
- **Prompt:** `As prgs-reconciler, dry-run then execute gitea_reconcile_merged_cleanups for recently merged PRs without switching to prgs-author.`
|
||||
|
||||
### Stop on blocker
|
||||
|
||||
- **Any profile.** If a required gate cannot be satisfied — identity
|
||||
@@ -931,6 +974,7 @@ When posting a Canonical Thread Handoff after a binding blocker:
|
||||
|
||||
## Related documents
|
||||
|
||||
- [`issue-acceptance-gate.md`](issue-acceptance-gate.md) — controller issue-acceptance audit after PR merge (#500).
|
||||
- [`../skills/llm-project-workflow/SKILL.md`](../skills/llm-project-workflow/SKILL.md) — portable cross-project LLM workflow skill.
|
||||
- [`gitea-execution-profiles.md`](gitea-execution-profiles.md) — the profile model.
|
||||
- [`gitea-dual-namespace-deployment.md`](gitea-dual-namespace-deployment.md) — static author/reviewer namespace deployment (#139 decision).
|
||||
@@ -940,6 +984,21 @@ When posting a Canonical Thread Handoff after a binding blocker:
|
||||
- [`credential-isolation.md`](credential-isolation.md) — credential handling.
|
||||
- [`release-workflows.md`](release-workflows.md) — release/merge workflow.
|
||||
- [`../README.md`](../README.md) — canonical config, thin launchers, the menu.
|
||||
- [`state-handoff-ledger.md`](state-handoff-ledger.md) — canonical state comments and next-action handoff (#494).
|
||||
|
||||
## Canonical state handoff ledger (#494)
|
||||
|
||||
Gitea comments and final reports must make continuation obvious without chat
|
||||
history. See [`state-handoff-ledger.md`](state-handoff-ledger.md) for:
|
||||
|
||||
- discussion → issue → PR → review → merge → reconcile lifecycle
|
||||
- templates for discussion, issue, PR, and queue-controller state comments
|
||||
- final-report requirements: Current status, Next actor, Next action, Next prompt
|
||||
- queue-controller priority order and discussion ≥5-comment rule (urgent/trivial
|
||||
exceptions)
|
||||
|
||||
Helpers live in `state_handoff_ledger.py`; final-report enforcement is wired
|
||||
through `assess_final_report_validator`.
|
||||
|
||||
## PR-only queue cleanup mode (#390)
|
||||
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@ The script must be executable (`chmod +x mcp-menu.sh`). It uses bash with
|
||||
|--------|-------------|
|
||||
| Project status / root checkout health | Shows cwd, branch, `git status --short --branch`, HEAD SHA, `prgs/master` SHA, and warnings when the root checkout is dirty or off `master`. |
|
||||
| Author workflow prompts | Ready-to-copy prompts for issue work, conflict-fix sessions, and root checkout recovery. |
|
||||
| Reviewer workflow prompts | PR review prompt (review-only; no merge). |
|
||||
| Reviewer workflow prompts | Standard PR review prompt, and a skip-already-reviewed-stale-`REQUEST_CHANGES` prompt that hands off to the author without a duplicate terminal mutation (review-only; no merge). |
|
||||
| Merger workflow prompts | PR merge prompt (merge gates and explicit approval). |
|
||||
| Reconciler workflow prompts | Already-landed / closed PR reconciliation prompt. |
|
||||
| Onboarding new project | Checklist prompt for adding a repository to the MCP workflow. |
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
# Canonical state handoff ledger (#494)
|
||||
|
||||
Gitea is the system of record for continuation. Every discussion, issue, and PR
|
||||
should answer: current state, last proof, who acts next, and the exact prompt for
|
||||
the next role.
|
||||
|
||||
## Lifecycle
|
||||
|
||||
1. Controller opens a discussion.
|
||||
2. Discussion accumulates substantive comments (default minimum: five).
|
||||
3. Controller posts a discussion summary when ready.
|
||||
4. Controller creates linked issues from the summary.
|
||||
5. Author locks issue, implements, opens PR.
|
||||
6. Reviewer reviews at current head.
|
||||
7. Merger merges after formal approval.
|
||||
8. Reconciler closes superseded or already-landed PRs.
|
||||
9. Issue/PR/discussion state comments make the next action obvious at every step.
|
||||
|
||||
## Discussion rules
|
||||
|
||||
- Do **not** convert a discussion into issues until it has at least **five
|
||||
substantive comments**, unless the discussion state comment marks
|
||||
`URGENCY: urgent` or `URGENCY: trivial`.
|
||||
- Substantive comment types: proposal, risk/concern, acceptance criteria,
|
||||
implementation approach, dependency/sequence, summary.
|
||||
- Before issue creation, post a **discussion summary** with decision, issues to
|
||||
create, non-goals, unresolved questions, and next prompt.
|
||||
- Created issues must link back to the discussion; the discussion must link
|
||||
forward to created issues.
|
||||
|
||||
## State comment templates
|
||||
|
||||
Use `state_handoff_ledger.py` helpers or copy the canonical blocks:
|
||||
|
||||
- `render_discussion_state_comment(...)`
|
||||
- `render_discussion_summary_comment(...)`
|
||||
- `render_issue_state_comment(...)`
|
||||
- `render_pr_state_comment(...)`
|
||||
- `render_queue_controller_report(...)`
|
||||
|
||||
Post state comments as the **latest canonical update** on the object. Do not
|
||||
bury state inside PR bodies only.
|
||||
|
||||
## Final report requirements
|
||||
|
||||
Every final report must include a `Controller Handoff` section with:
|
||||
|
||||
- **Current status** — live state after this session
|
||||
- **Next actor** — `author`, `reviewer`, `merger`, `reconciler`, or `controller`
|
||||
- **Next action** — one imperative step
|
||||
- **Next prompt** — ready-to-paste prompt for the next role
|
||||
|
||||
`assess_final_report_next_action_handoff` and
|
||||
`assess_contradictory_state_handoff` enforce these fields and reject
|
||||
contradictory claims (for example, ready-to-merge without approval, issue done
|
||||
without PR proof, discussion complete without summary).
|
||||
|
||||
## Queue controller selection (priority order)
|
||||
|
||||
1. Merge clean approved PRs at current head.
|
||||
2. Review PRs needing review.
|
||||
3. Reconcile superseded or already-landed duplicates.
|
||||
4. Continue blocked-but-now-unblocked issues.
|
||||
5. Create issues from completed discussions.
|
||||
6. Start new author work only when higher-priority queue items are clear.
|
||||
|
||||
For each candidate object, read the **latest canonical state comment** before
|
||||
choosing an action. Output the exact next-role prompt in the controller report.
|
||||
|
||||
## Example workflow states
|
||||
|
||||
| State | Next actor | Typical next action |
|
||||
|-------|------------|---------------------|
|
||||
| Discussion needs more comments | controller | Facilitate discussion until five substantive comments or urgent/trivial exception |
|
||||
| Issue ready for author | author | Lock issue and implement in `branches/` worktree |
|
||||
| PR needs review | reviewer | Review at pinned head in reviewer worktree |
|
||||
| PR approved at head | merger | Merge with merger profile after eligibility proof |
|
||||
| PR superseded | reconciler | Close duplicate/already-landed PR with proof |
|
||||
| Issue blocked | controller | Post issue state comment with blockers and next prompt |
|
||||
|
||||
## Non-goals
|
||||
|
||||
- Chat history is not the source of truth.
|
||||
- Do not weaken author/reviewer/merger/reconciler separation.
|
||||
- Do not replace Gitea issues, PRs, or canonical workflow files under
|
||||
`skills/llm-project-workflow/`.
|
||||
+11
-2
@@ -46,7 +46,8 @@ Optional environment variables:
|
||||
| `/runtime` | Stub — MCP runtime health (#430) |
|
||||
| `/audit` | Stub — report audit paste (#431) |
|
||||
| `/worktrees` | Stub — hygiene dashboard (#432) |
|
||||
| `/leases` | Stub — lease visibility (#433) |
|
||||
| `/leases` | Lease and collision visibility (#433) |
|
||||
| `/api/leases` | JSON lease/collision export |
|
||||
|
||||
All routes are GET-only. POST/PUT/PATCH/DELETE return `405` with
|
||||
`read-only-mvp`.
|
||||
@@ -82,8 +83,16 @@ credentials. The UI surfaces pagination proof (returned count, pages fetched,
|
||||
If credentials are missing or the fetch fails, the page shows an explicit error
|
||||
instead of an empty queue (fail closed).
|
||||
|
||||
## Lease visibility (#433)
|
||||
|
||||
`/leases` surfaces read-only lease and collision state: local issue lock file,
|
||||
in-progress claim inventory (#268), reviewer PR lease comments when present
|
||||
(`<!-- mcp-review-lease:v1 -->`, #407), duplicate open PRs per issue (#400),
|
||||
and duplicate local branches per issue. Links to collision-history backend
|
||||
issues (#267, #268, #400, #407) are included. No lease acquire/release from UI.
|
||||
|
||||
## Tests
|
||||
|
||||
```bash
|
||||
pytest tests/test_webui_skeleton.py tests/test_webui_project_registry.py tests/test_webui_prompt_library.py tests/test_webui_queue_dashboard.py -q
|
||||
pytest tests/test_webui_skeleton.py tests/test_webui_project_registry.py tests/test_webui_prompt_library.py tests/test_webui_queue_dashboard.py tests/test_webui_lease_visibility.py -q
|
||||
```
|
||||
Reference in New Issue
Block a user