From e11deb8218763242c1c1cf25ba0d15fc130292ae Mon Sep 17 00:00:00 2001 From: Jason Walker <913443@dadeschools.net> Date: Wed, 8 Jul 2026 15:42:45 -0400 Subject: [PATCH] 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. --- docs/llm-workflow-runbooks.md | 2 + skills/llm-project-workflow/SKILL.md | 33 +++++++++++- .../templates/blocked-diagnose-report.md | 52 +++++++++++++++++++ .../templates/merge-pr.md | 1 + .../templates/recover-bad-state.md | 21 ++++++-- .../templates/review-pr.md | 1 + .../templates/start-issue.md | 1 + .../workflows/create-issue.md | 2 + .../workflows/review-merge-pr.md | 2 + .../workflows/work-issue.md | 2 + 10 files changed, 112 insertions(+), 5 deletions(-) create mode 100644 skills/llm-project-workflow/templates/blocked-diagnose-report.md diff --git a/docs/llm-workflow-runbooks.md b/docs/llm-workflow-runbooks.md index fa2add5..9f820ad 100644 --- a/docs/llm-workflow-runbooks.md +++ b/docs/llm-workflow-runbooks.md @@ -28,6 +28,8 @@ audit logging). See [Related documents](#related-documents). > to discover the available project workflows and `mcp_get_skill_guide()` > for step-by-step instructions. This replaces long pasted operator prompts for > 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. Jenkins and GlitchTip workflows use separate MCP servers, not this Gitea MCP diff --git a/skills/llm-project-workflow/SKILL.md b/skills/llm-project-workflow/SKILL.md index dc2f961..d5aee2d 100644 --- a/skills/llm-project-workflow/SKILL.md +++ b/skills/llm-project-workflow/SKILL.md @@ -31,12 +31,29 @@ workflow file. - A nearby capability does not count. - Do not self-review or self-merge. - 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 - only. + only (see BLOCKED + DIAGNOSE rule above). - Final report must use the schema for the loaded workflow. - If a task requires a different mode, stop and produce a handoff for the 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 A run that starts in `review-merge-pr` mode may not create process issues, @@ -182,4 +199,16 @@ Ready-to-copy task prompts live in [`templates/`](templates/): Releases follow SemVer from remote `master` only, after full test suite passes. See [`templates/release-tag.md`](templates/release-tag.md) and -`scripts/release-tag`. \ No newline at end of file +`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. \ No newline at end of file diff --git a/skills/llm-project-workflow/templates/blocked-diagnose-report.md b/skills/llm-project-workflow/templates/blocked-diagnose-report.md new file mode 100644 index 0000000..d4737eb --- /dev/null +++ b/skills/llm-project-workflow/templates/blocked-diagnose-report.md @@ -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 + + +## Observed failure + + +## Expected behavior + + +## 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: + +## Durable fix recommendation + + +## 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 + + +--- + +**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. \ No newline at end of file diff --git a/skills/llm-project-workflow/templates/merge-pr.md b/skills/llm-project-workflow/templates/merge-pr.md index a0ee00d..626cac8 100644 --- a/skills/llm-project-workflow/templates/merge-pr.md +++ b/skills/llm-project-workflow/templates/merge-pr.md @@ -10,6 +10,7 @@ Load the canonical workflow first: Final report schema: `schemas/review-merge-final-report.md`. 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 author → STOP. - Do not merge unless the PR is open, mergeable, and its checks/review pass. diff --git a/skills/llm-project-workflow/templates/recover-bad-state.md b/skills/llm-project-workflow/templates/recover-bad-state.md index 343a096..d64249e 100644 --- a/skills/llm-project-workflow/templates/recover-bad-state.md +++ b/skills/llm-project-workflow/templates/recover-bad-state.md @@ -3,12 +3,15 @@ Copy, fill the `<...>` fields, paste as the task prompt. Recovery is read-then- 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 Task: recover repo state for . Do not lose unmerged work. 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 . +- Prove you are in a branches/ worktree before any recovery mutation. Diagnose first: 1. git fetch --prune @@ -16,8 +19,19 @@ Diagnose first: 3. git rev-list --left-right --count /master...master # ahead/behind 4. For any PR involved: confirm state (open/closed/merged) AND whether /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 + + +## 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. - Local master ahead of remote: confirm the extra commits live on a branch pushed to , THEN git reset --hard /master. Verify with @@ -26,6 +40,7 @@ Act per case: - Branch deleted before merge: recover commits from a local branch/reflog (or git fsck --lost-found), re-push, reopen the PR. - 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. ``` diff --git a/skills/llm-project-workflow/templates/review-pr.md b/skills/llm-project-workflow/templates/review-pr.md index 391f962..25bd808 100644 --- a/skills/llm-project-workflow/templates/review-pr.md +++ b/skills/llm-project-workflow/templates/review-pr.md @@ -35,6 +35,7 @@ Load the canonical workflow first: Final report schema: `schemas/review-merge-final-report.md`. 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. - Worktree safety (#233): before checkout, diff, validation, review, or merge, report the starting worktree path and whether it was dirty. If unrelated diff --git a/skills/llm-project-workflow/templates/start-issue.md b/skills/llm-project-workflow/templates/start-issue.md index 4b8c159..d58b21b 100644 --- a/skills/llm-project-workflow/templates/start-issue.md +++ b/skills/llm-project-workflow/templates/start-issue.md @@ -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) 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; if it can't be created, stop. - Work only in an isolated branch worktree under branches/. The main checkout diff --git a/skills/llm-project-workflow/workflows/create-issue.md b/skills/llm-project-workflow/workflows/create-issue.md index 00f34f8..1c4029f 100644 --- a/skills/llm-project-workflow/workflows/create-issue.md +++ b/skills/llm-project-workflow/workflows/create-issue.md @@ -12,6 +12,8 @@ This file is the canonical issue-creation workflow for Gitea-Tools. Load it before any issue mutation. Final report schema: [`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:** > Create or update Gitea issues in this project only if every identity, diff --git a/skills/llm-project-workflow/workflows/review-merge-pr.md b/skills/llm-project-workflow/workflows/review-merge-pr.md index 44b9f12..3f94c6f 100644 --- a/skills/llm-project-workflow/workflows/review-merge-pr.md +++ b/skills/llm-project-workflow/workflows/review-merge-pr.md @@ -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: [`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:** > Review the next eligible open PR in this project. Merge it only if every diff --git a/skills/llm-project-workflow/workflows/work-issue.md b/skills/llm-project-workflow/workflows/work-issue.md index f4dff71..13ed174 100644 --- a/skills/llm-project-workflow/workflows/work-issue.md +++ b/skills/llm-project-workflow/workflows/work-issue.md @@ -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: [`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:** > Find the next eligible issue in this project, work on it only if all gates