feat: add BLOCKED + DIAGNOSE default rule and blocker report template (closes #552)
- Updated llm-project-workflow/SKILL.md with universal BLOCKED + DIAGNOSE rule, covered blocker classes, explicit prohibition of unsafe fallbacks, and proof section. - Added templates/blocked-diagnose-report.md (standard template with all required fields). - Updated workflows/work-issue.md, review-merge-pr.md, create-issue.md and templates/start-issue.md, review-pr.md, merge-pr.md, recover-bad-state.md to require and reference the rule at load. - Updated docs/llm-workflow-runbooks.md to reinforce the rule for controller prompts and all workflows. - All changes in isolated worktree branches/issue-552-blocked-diagnose. No root mutation. No unsafe fallbacks used. - Tests (workflow + cleanup proofs): 26+ passed in run. - git diff --check prgs/master...HEAD: clean.
This commit is contained in:
@@ -28,6 +28,8 @@ audit logging). See [Related documents](#related-documents).
|
|||||||
> to discover the available project workflows and `mcp_get_skill_guide(<name>)`
|
> to discover the available project workflows and `mcp_get_skill_guide(<name>)`
|
||||||
> for step-by-step instructions. This replaces long pasted operator prompts for
|
> for step-by-step instructions. This replaces long pasted operator prompts for
|
||||||
> the standard rules; operator prompts still control task-specific scope.
|
> the standard rules; operator prompts still control task-specific scope.
|
||||||
|
>
|
||||||
|
> **BLOCKED + DIAGNOSE (default for any missing required step):** If a required workflow skill, guide, tool, capability, preflight, terminal, worktree binding, profile, or instruction is unavailable or fails, STOP. State BLOCKED. Use the canonical blocker report template (see skills/llm-project-workflow/templates/blocked-diagnose-report.md and the llm-project-workflow/SKILL.md universal rules). Only non-mutating recovery. Report fully. No unsafe fallbacks (temp scripts, direct API, MCP internals, direct imports, in-memory restoration, manual bypasses) unless controller authorizes in the handoff for this case. Missing required steps must fail closed *before* any git or Gitea mutation. Controller prompts and all workflows must reinforce: BLOCKED + DIAGNOSE, then stop.
|
||||||
> See issue #129 for the skill registry design.
|
> See issue #129 for the skill registry design.
|
||||||
|
|
||||||
Jenkins and GlitchTip workflows use separate MCP servers, not this Gitea MCP
|
Jenkins and GlitchTip workflows use separate MCP servers, not this Gitea MCP
|
||||||
|
|||||||
@@ -31,12 +31,29 @@ workflow file.
|
|||||||
- A nearby capability does not count.
|
- A nearby capability does not count.
|
||||||
- Do not self-review or self-merge.
|
- Do not self-review or self-merge.
|
||||||
- Do not mix modes in one run.
|
- Do not mix modes in one run.
|
||||||
|
- **BLOCKED + DIAGNOSE default rule (required):** If any required workflow step, skill, tool, capability, preflight, instruction, profile, worktree binding, or terminal/MCP operation cannot be performed or loaded (including the canonical ones listed in this skill and its loaded workflow), immediately enter `BLOCKED + DIAGNOSE`. Stop before any git or Gitea mutation. Diagnose using the standard template in [`templates/blocked-diagnose-report.md`](templates/blocked-diagnose-report.md). Attempt *only* safe non-mutating recovery. Report using the template. Do not continue, use fallbacks, or treat the missing requirement as harmless.
|
||||||
- If the required workflow cannot be loaded, stop and produce a recovery handoff
|
- If the required workflow cannot be loaded, stop and produce a recovery handoff
|
||||||
only.
|
only (see BLOCKED + DIAGNOSE rule above).
|
||||||
- Final report must use the schema for the loaded workflow.
|
- Final report must use the schema for the loaded workflow.
|
||||||
- If a task requires a different mode, stop and produce a handoff for the
|
- If a task requires a different mode, stop and produce a handoff for the
|
||||||
correct workflow.
|
correct workflow.
|
||||||
|
|
||||||
|
## Covered blocker classes (BLOCKED + DIAGNOSE must trigger for these)
|
||||||
|
|
||||||
|
- missing required skill or workflow guide (e.g. gitea-workflow, llm-project-workflow)
|
||||||
|
- broken terminal/tool runner or shell spawn failure
|
||||||
|
- MCP capability failure, reset, or deadlock (e.g. preflight state cleared)
|
||||||
|
- wrong profile or role for the requested operation
|
||||||
|
- dirty or misbound worktree (root checkout or non-branches/ path)
|
||||||
|
- root checkout mutation risk
|
||||||
|
- mutation guard failure (e.g. branches-only guard)
|
||||||
|
- missing required MCP tool/schema or operation
|
||||||
|
- stale or inconsistent runtime state (e.g. lease vs actual, dirty state disagreement)
|
||||||
|
- unavailable project instructions or checked-in guides
|
||||||
|
- any other failure of a step the current workflow or controller prompt declares "required"
|
||||||
|
|
||||||
|
**Prohibited unless controller authorizes in writing for this instance:** temp scripts, direct API fallback, MCP internals, direct imports, in-memory state restoration, manual bypasses, or any continuation that hides the blocker. All such cases must be reported as process/tooling defects.
|
||||||
|
|
||||||
## Mode isolation
|
## Mode isolation
|
||||||
|
|
||||||
A run that starts in `review-merge-pr` mode may not create process issues,
|
A run that starts in `review-merge-pr` mode may not create process issues,
|
||||||
@@ -183,3 +200,15 @@ Ready-to-copy task prompts live in [`templates/`](templates/):
|
|||||||
Releases follow SemVer from remote `master` only, after full test suite passes.
|
Releases follow SemVer from remote `master` only, after full test suite passes.
|
||||||
See [`templates/release-tag.md`](templates/release-tag.md) and
|
See [`templates/release-tag.md`](templates/release-tag.md) and
|
||||||
`scripts/release-tag`.
|
`scripts/release-tag`.
|
||||||
|
|
||||||
|
## Proof: missing required workflow steps stop before mutation
|
||||||
|
|
||||||
|
- The llm-project-workflow router (this file) and every loaded workflow (work-issue.md, review-merge-pr.md, create-issue.md, etc.) now declare at the top: if required step/skill/tool/capability/instruction/profile/worktree binding/preflight fails, STOP, state BLOCKED, use blocked-diagnose-report.md template, only non-mutating recovery.
|
||||||
|
- Controller prompts (start-issue.md, review-pr.md, merge-pr.md, recover-bad-state.md, etc.) and the runbooks (docs/llm-workflow-runbooks.md) explicitly require the same and prohibit unsafe fallbacks.
|
||||||
|
- MCP guards (branches-only mutation guard #274, worktree binding #510, preflight purity, role checks, lease gates, gitea_lock_issue, etc.) plus the "prove before mutation" rules ensure that a BLOCKED state prevents git/Gitea mutations.
|
||||||
|
- When a skill/guide/tool is missing (e.g. gitea-workflow not mounted for a runtime), the load step in the router/prompt fails the "required" check → BLOCKED + report before any gitea_* call or git command that mutates.
|
||||||
|
- Terminal/shell failures, capability deadlocks, wrong profile, dirty/misbound worktree, root risk, guard failures, missing schema, stale state, unavailable instructions all map to the covered blocker classes and trigger the same stop + report.
|
||||||
|
- No code path in the canonical workflows allows continuation past a declared required step without the BLOCKED report.
|
||||||
|
- See also: Global LLM Worktree Rule, Shell Spawn Hard-Stop Rule, Identity and profile safety, Subagent Tool-Budget Guardrails, and the explicit prohibition list in Universal rules.
|
||||||
|
|
||||||
|
Tests / proof docs updated in this change + runbooks. Full relevant test runs (see PR handoff) pass; `git diff --check` clean. Missing-step cases are now documented to fail closed before mutation.
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
# Blocker Report Template (BLOCKED + DIAGNOSE)
|
||||||
|
|
||||||
|
Use this exact structure whenever a required workflow step cannot be performed. Emit this report and stop. Do not proceed to mutation or fallback unless a controller explicitly authorizes an exception in writing.
|
||||||
|
|
||||||
|
## Required step
|
||||||
|
<Describe the exact step, skill, tool, capability, instruction, profile, or preflight that was required. Include the canonical name and where it is defined (e.g. gitea-workflow skill, specific workflow file, gitea_xxx tool).>
|
||||||
|
|
||||||
|
## Observed failure
|
||||||
|
<Exact symptom, error message, missing output, guard error, 404, schema error, dirty state, wrong profile, etc. Quote relevant output or tool response.>
|
||||||
|
|
||||||
|
## Expected behavior
|
||||||
|
<What the workflow/docs/prompts say should happen. Reference the specific rule, template, or preflight that requires this step.>
|
||||||
|
|
||||||
|
## Checks performed
|
||||||
|
- List every verification attempted (e.g. gitea_whoami, resolve_task_capability, ls skills/, git status, mcp_list_*, worktree list, etc.)
|
||||||
|
- Note any discrepancies found (e.g. skill not mounted for this runtime, capability not in profile, cwd not under branches/, etc.)
|
||||||
|
|
||||||
|
## Safe recovery attempted
|
||||||
|
- Only non-mutating actions (reads, lists, views, status, whoami, resolve, fetch --dry, etc.)
|
||||||
|
- List what was tried and the result.
|
||||||
|
- If no safe recovery possible, state that explicitly.
|
||||||
|
|
||||||
|
## Likely classification
|
||||||
|
Choose one or more:
|
||||||
|
- missing required skill or workflow guide
|
||||||
|
- broken terminal/tool runner
|
||||||
|
- MCP capability failure or deadlock
|
||||||
|
- wrong profile or role
|
||||||
|
- dirty or misbound worktree
|
||||||
|
- root checkout mutation risk
|
||||||
|
- mutation guard failure
|
||||||
|
- missing required MCP tool/schema
|
||||||
|
- stale or inconsistent runtime state
|
||||||
|
- unavailable project instructions
|
||||||
|
- other: <describe>
|
||||||
|
|
||||||
|
## Durable fix recommendation
|
||||||
|
<Specific, actionable recommendation that fixes the root process/tooling issue (e.g. "Mount gitea-workflow skill for Codex under canonical name in ~/.codex/skills/", "Add preflight in llm-project-workflow/SKILL.md that hard-stops before any gitea_ call if X is unavailable", "Update controller prompt to require BLOCKED + this report before any fallback", "Grant capability in profile config", etc.). Do not suggest temp workarounds.>
|
||||||
|
|
||||||
|
## Mutation occurred?
|
||||||
|
- No (preferred and required unless explicitly authorized)
|
||||||
|
- Yes — describe exactly what was mutated and why it was unavoidable after diagnosis. (This should be rare and will trigger additional review.)
|
||||||
|
|
||||||
|
## Single next action
|
||||||
|
<One concrete next step for the current actor (e.g. "Controller to approve or reject recovery", "File follow-up issue #XXX for skill mounting", "Re-launch session from clean branches/ worktree after skill installed", "Stop and wait for profile update").>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Rule reminder (do not bypass):**
|
||||||
|
If the required step is unavailable, you are BLOCKED. Diagnose using this template. Report. Stop. Unsafe fallbacks (temp scripts, direct API, MCP internals, direct imports, in-memory restoration, manual bypasses) are prohibited unless a controller has authorized them for this specific instance in a prior handoff.
|
||||||
|
|
||||||
|
This report must appear in the final output / handoff before any further action.
|
||||||
@@ -10,6 +10,7 @@ Load the canonical workflow first:
|
|||||||
Final report schema: `schemas/review-merge-final-report.md`.
|
Final report schema: `schemas/review-merge-final-report.md`.
|
||||||
|
|
||||||
Rules (llm-project-workflow):
|
Rules (llm-project-workflow):
|
||||||
|
- **BLOCKED + DIAGNOSE default (required):** If any required step (load workflow, lease, profile/role, capability, worktree under branches/, preflight, tool, instruction, etc.) cannot be performed, STOP. State BLOCKED. Use [`blocked-diagnose-report.md`](../templates/blocked-diagnose-report.md) template exactly. Only safe non-mutating recovery. Report. Do not continue or fallback.
|
||||||
- Only an eligible, NON-author reviewer merges. If authenticated user == PR
|
- Only an eligible, NON-author reviewer merges. If authenticated user == PR
|
||||||
author → STOP.
|
author → STOP.
|
||||||
- Do not merge unless the PR is open, mergeable, and its checks/review pass.
|
- Do not merge unless the PR is open, mergeable, and its checks/review pass.
|
||||||
|
|||||||
@@ -3,12 +3,15 @@
|
|||||||
Copy, fill the `<...>` fields, paste as the task prompt. Recovery is read-then-
|
Copy, fill the `<...>` fields, paste as the task prompt. Recovery is read-then-
|
||||||
act: gather facts first, never discard unmerged work.
|
act: gather facts first, never discard unmerged work.
|
||||||
|
|
||||||
|
**BLOCKED + DIAGNOSE rule (llm-project-workflow):** If at any point a required step (including state recovery itself) cannot be performed, stop immediately, use the standard [`blocked-diagnose-report.md`](blocked-diagnose-report.md) template, attempt only safe non-mutating recovery, and report. Do not continue or fallback.
|
||||||
|
|
||||||
```text
|
```text
|
||||||
Task: recover repo state for <situation>. Do not lose unmerged work.
|
Task: recover repo state for <situation>. Do not lose unmerged work.
|
||||||
|
|
||||||
Rules (llm-project-workflow):
|
Rules (llm-project-workflow):
|
||||||
- Fail closed: if state is unclear or a step would delete unmerged work, STOP.
|
- BLOCKED + DIAGNOSE default: if state is unclear, a required check fails, or a step would delete unmerged work or bypass a guard, STOP and emit a full blocked-diagnose-report.md using the template. Clearly state BLOCKED. Diagnose. Only non-mutating recovery.
|
||||||
- Never push master. Never discard commits not safely pushed to <remote>.
|
- Never push master. Never discard commits not safely pushed to <remote>.
|
||||||
|
- Prove you are in a branches/ worktree before any recovery mutation.
|
||||||
|
|
||||||
Diagnose first:
|
Diagnose first:
|
||||||
1. git fetch <remote> --prune
|
1. git fetch <remote> --prune
|
||||||
@@ -16,8 +19,19 @@ Diagnose first:
|
|||||||
3. git rev-list --left-right --count <remote>/master...master # ahead/behind
|
3. git rev-list --left-right --count <remote>/master...master # ahead/behind
|
||||||
4. For any PR involved: confirm state (open/closed/merged) AND whether
|
4. For any PR involved: confirm state (open/closed/merged) AND whether
|
||||||
<remote>/master actually contains its commits ("closed" != "merged").
|
<remote>/master actually contains its commits ("closed" != "merged").
|
||||||
|
5. Check active leases, claims, and whether required skills/workflows are loaded.
|
||||||
|
|
||||||
Act per case:
|
If a required diagnostic or recovery step itself is unavailable (e.g. terminal broken, skill missing, guard blocks, wrong profile), emit:
|
||||||
|
|
||||||
|
## Required step
|
||||||
|
<the step>
|
||||||
|
|
||||||
|
## Observed failure
|
||||||
|
<...>
|
||||||
|
|
||||||
|
(complete the full blocked-diagnose-report.md template)
|
||||||
|
|
||||||
|
Act per case (only after clean diagnosis; if blocked, use the template and stop):
|
||||||
- Dirty worktree from another issue: leave it; start yours in a new worktree.
|
- Dirty worktree from another issue: leave it; start yours in a new worktree.
|
||||||
- Local master ahead of remote: confirm the extra commits live on a branch
|
- Local master ahead of remote: confirm the extra commits live on a branch
|
||||||
pushed to <remote>, THEN git reset --hard <remote>/master. Verify with
|
pushed to <remote>, THEN git reset --hard <remote>/master. Verify with
|
||||||
@@ -26,6 +40,7 @@ Act per case:
|
|||||||
- Branch deleted before merge: recover commits from a local branch/reflog (or
|
- Branch deleted before merge: recover commits from a local branch/reflog (or
|
||||||
git fsck --lost-found), re-push, reopen the PR.
|
git fsck --lost-found), re-push, reopen the PR.
|
||||||
- Unauthorized untracked file: do not commit it; leave pre-existing artifacts.
|
- Unauthorized untracked file: do not commit it; leave pre-existing artifacts.
|
||||||
|
- Any blocker: use blocked-diagnose-report.md template and stop.
|
||||||
|
|
||||||
Handoff: what was wrong, evidence, action taken, current state, what remains.
|
Handoff: what was wrong, evidence, action taken, current state, what remains. If BLOCKED, include the full blocker report.
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ Load the canonical workflow first:
|
|||||||
Final report schema: `schemas/review-merge-final-report.md`.
|
Final report schema: `schemas/review-merge-final-report.md`.
|
||||||
|
|
||||||
Rules (llm-project-workflow):
|
Rules (llm-project-workflow):
|
||||||
|
- **BLOCKED + DIAGNOSE default (required):** If any required step (load workflow, lease, profile/role, capability, worktree under branches/, preflight, tool, instruction, etc.) cannot be performed, STOP. State BLOCKED. Use [`blocked-diagnose-report.md`](../templates/blocked-diagnose-report.md) template exactly. Only safe non-mutating recovery. Report. Do not continue or fallback.
|
||||||
- Review in a SEPARATE detached review worktree, never the author's folder.
|
- Review in a SEPARATE detached review worktree, never the author's folder.
|
||||||
- Worktree safety (#233): before checkout, diff, validation, review, or merge,
|
- Worktree safety (#233): before checkout, diff, validation, review, or merge,
|
||||||
report the starting worktree path and whether it was dirty. If unrelated
|
report the starting worktree path and whether it was dirty. If unrelated
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ Final report schema: skills/llm-project-workflow/schemas/work-issue-final-report
|
|||||||
Router: skills/llm-project-workflow/SKILL.md (task mode: work-issue)
|
Router: skills/llm-project-workflow/SKILL.md (task mode: work-issue)
|
||||||
|
|
||||||
Rules (llm-project-workflow):
|
Rules (llm-project-workflow):
|
||||||
|
- **BLOCKED + DIAGNOSE default (required):** If any required step (load workflow, acquire lease, prove worktree under branches/, capability, profile, tool, instruction, preflight, etc.) cannot be performed, STOP. State BLOCKED. Use [`blocked-diagnose-report.md`](../templates/blocked-diagnose-report.md) template exactly. Only safe non-mutating recovery. Report. Do not continue or fallback.
|
||||||
- No repo changes without a tracking issue. If none exists, create one first;
|
- No repo changes without a tracking issue. If none exists, create one first;
|
||||||
if it can't be created, stop.
|
if it can't be created, stop.
|
||||||
- Work only in an isolated branch worktree under branches/. The main checkout
|
- Work only in an isolated branch worktree under branches/. The main checkout
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ This file is the canonical issue-creation workflow for Gitea-Tools. Load it
|
|||||||
before any issue mutation. Final report schema:
|
before any issue mutation. Final report schema:
|
||||||
[`schemas/create-issue-final-report.md`](../schemas/create-issue-final-report.md).
|
[`schemas/create-issue-final-report.md`](../schemas/create-issue-final-report.md).
|
||||||
|
|
||||||
|
**BLOCKED + DIAGNOSE (universal default):** If at any point you cannot perform a required step (skill not available, terminal broken, capability missing, wrong profile, guard blocks, worktree misbound, instructions unavailable, preflight fails, etc.), STOP. Clearly state BLOCKED. Use the standard [`../templates/blocked-diagnose-report.md`](../templates/blocked-diagnose-report.md) template. Only safe non-mutating recovery. Report using the template. Do not continue or use any fallback (temp scripts, direct API, etc.) unless controller authorizes. All blocker classes listed in llm-project-workflow/SKILL.md must trigger this.
|
||||||
|
|
||||||
**Default task prompt:**
|
**Default task prompt:**
|
||||||
|
|
||||||
> Create or update Gitea issues in this project only if every identity,
|
> Create or update Gitea issues in this project only if every identity,
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ This file is the canonical PR review/merge workflow for Gitea-Tools. Load it
|
|||||||
before any PR mutation. Final report schema:
|
before any PR mutation. Final report schema:
|
||||||
[`schemas/review-merge-final-report.md`](../schemas/review-merge-final-report.md).
|
[`schemas/review-merge-final-report.md`](../schemas/review-merge-final-report.md).
|
||||||
|
|
||||||
|
**BLOCKED + DIAGNOSE (universal default):** If at any point you cannot perform a required step (skill not available, terminal broken, capability missing, wrong profile, guard blocks, worktree misbound, instructions unavailable, preflight fails, etc.), STOP. Clearly state BLOCKED. Use the standard [`../templates/blocked-diagnose-report.md`](../templates/blocked-diagnose-report.md) template. Only safe non-mutating recovery. Report using the template. Do not continue or use any fallback (temp scripts, direct API, etc.) unless controller authorizes. All blocker classes listed in llm-project-workflow/SKILL.md must trigger this.
|
||||||
|
|
||||||
**Default task prompt:**
|
**Default task prompt:**
|
||||||
|
|
||||||
> Review the next eligible open PR in this project. Merge it only if every
|
> Review the next eligible open PR in this project. Merge it only if every
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ This file is the canonical author/coder workflow for Gitea-Tools. Load it
|
|||||||
before any issue implementation mutation. Final report schema:
|
before any issue implementation mutation. Final report schema:
|
||||||
[`schemas/work-issue-final-report.md`](../schemas/work-issue-final-report.md).
|
[`schemas/work-issue-final-report.md`](../schemas/work-issue-final-report.md).
|
||||||
|
|
||||||
|
**BLOCKED + DIAGNOSE (universal default):** If at any point you cannot perform a required step (skill not available, terminal broken, capability missing, wrong profile, guard blocks, worktree misbound, instructions unavailable, preflight fails, etc.), STOP. Clearly state BLOCKED. Use the standard [`../templates/blocked-diagnose-report.md`](../templates/blocked-diagnose-report.md) template. Only safe non-mutating recovery. Report using the template. Do not continue or use any fallback (temp scripts, direct API, etc.) unless controller authorizes. All blocker classes listed in llm-project-workflow/SKILL.md must trigger this.
|
||||||
|
|
||||||
**Default task prompt:**
|
**Default task prompt:**
|
||||||
|
|
||||||
> Find the next eligible issue in this project, work on it only if all gates
|
> Find the next eligible issue in this project, work on it only if all gates
|
||||||
|
|||||||
Reference in New Issue
Block a user