Skip to content
Development
Command

/diagnose

Trace a failed or stalled pipeline run — identify which FORGE annotation is missing or malformed, diagnose the failure point, and suggest specific remediation steps

BOOST
From plugin
forgedock
11980 skills80 commands
Install
> /plugin marketplace add RapierCraftStudios/ForgeDock
> /plugin install forgedock@forgedock

How it fires

How this command gets triggered: by you, by Claude, or both.

  • Fires itselfClaude auto-loads it when your prompt matches the work.
  • You can call itInvoke it directly when you want it.
  • Slash command/diagnose

Context preview

What this command does when you run it.

Trace a failed or stalled pipeline run — identify which FORGE annotation is missing or malformed, diagnose the failure point, and suggest specific remediation steps

Command definition

diagnose.md
description: Trace a failed or stalled pipeline run — identify which FORGE annotation is missing or malformed, diagnose the failure point, and suggest specific remediation steps
argument-hint: "[issue number] [--repo prefix]"
install: extras

/diagnose — Pipeline Failure Tracer

**Input**: $ARGUMENTS

**NEVER use plan mode (EnterPlanMode)** — it breaks execution context.

**Agent model policy**: `model: "{DEFAULT_MODEL}"` — resolved from forge.yaml `agents.default_model`, else "sonnet" (standard tier). Fallback: `model: "opus"` if rate-limited. Feature gate: pass `effort` in Task/Skill spawns only on Claude Code >= 2.1.154.

You are the pipeline's diagnostic layer. Given a single GitHub issue number, you reconstruct the full FORGE annotation chain for that pipeline run, identify the exact failure point, and suggest specific remediation steps. This command is **read-only** — it never mutates GitHub state.

---

Config Resolution

Before executing any phase, read `forge.yaml` to resolve project references:

CONFIG_FILE="${FORGE_CONFIG:-forge.yaml}"
if [ -f "$CONFIG_FILE" ]; then
  GH_OWNER=$(yq '.project.owner' "$CONFIG_FILE")
  GH_REPO_NAME=$(yq '.project.repo' "$CONFIG_FILE")
  GH_REPO="${GH_OWNER}/${GH_REPO_NAME}"
  GH_FLAG="-R $GH_REPO"
  REPO_PATH=$(yq '.paths.root' "$CONFIG_FILE")
  # FORGE_REPO: the self-pipeline repo (may differ from GH_REPO for multi-repo setups)
  FORGE_REPO=$(yq '.project.forge_repo // ""' "$CONFIG_FILE")
  [ -z "$FORGE_REPO" ] && FORGE_REPO="$GH_REPO"
else
  echo "ERROR: forge.yaml not found. Run: npx forgedock init"
  exit 1
fi

Input Parsing

Parse `$ARGUMENTS` for:

  • **`{NUMBER}`** — issue number (required). Exit with usage message if absent.
  • **`--repo prefix`** — satellite repo prefix (optional). Look up in `forge.yaml → repos.satellites[]`.
NUMBER=$(echo "$ARGUMENTS" | grep -oE '^[0-9]+' | head -1)
if [ -z "$NUMBER" ]; then
  echo "Usage: /diagnose {issue-number} [--repo prefix]"
  echo "Example: /diagnose 611"
  exit 1
fi

# Optional satellite repo routing
REPO_PREFIX=$(echo "$ARGUMENTS" | grep -oE -- '--repo [^ ]+' | sed 's/--repo //' | head -1)
if [ -n "$REPO_PREFIX" ]; then
  SATELLITE_REPO=$(yq ".repos.satellites[] | select(.prefix == \"$REPO_PREFIX\") | .repo" "$CONFIG_FILE" 2>/dev/null)
  if [ -n "$SATELLITE_REPO" ] && [ "$SATELLITE_REPO" != "null" ]; then
    GH_REPO="$SATELLITE_REPO"
    GH_FLAG="-R $GH_REPO"
    echo "Satellite repo: $GH_REPO"
  else
    echo "WARNING: --repo prefix '$REPO_PREFIX' not found in forge.yaml — using default repo"
  fi
fi

---

Phase 1: Load Issue Context

1A: Fetch issue

ISSUE=$(gh issue view "$NUMBER" $GH_FLAG \
  --json number,title,body,labels,state,comments,milestone,createdAt,closedAt)

echo "Issue #$NUMBER: $(echo "$ISSUE" | jq -r '.title')"
echo "State: $(echo "$ISSUE" | jq -r '.state')"
echo "Labels: $(echo "$ISSUE" | jq -r '[.labels[].name] | join(", ")')"
echo "Created: $(echo "$ISSUE" | jq -r '.createdAt')"
[ "$(echo "$ISSUE" | jq -r '.closedAt')" != "null" ] && \
  echo "Closed: $(echo "$ISSUE" | jq -r '.closedAt')"

1B: Fetch all comments

COMMENTS=$(gh api "repos/${GH_REPO}/issues/${NUMBER}/comments" \
  --jq '[.[] | {id: .id, author: .user.login, body: .body, created_at: .created_at}]')

COMMENT_COUNT=$(echo "$COMMENTS" | jq 'length')
echo "Comments found: $COMMENT_COUNT"

1C: Extract workflow labels

WORKFLOW_LABELS=$(echo "$ISSUE" | jq -r '[.labels[].name | select(startswith("workflow:"))] | join(", ")')
echo "Workflow labels: ${WORKFLOW_LABELS:-none}"

---

Phase 2: Classify Annotation Chain

Walk the comments in creation order and classify each by FORGE marker.

**Canonical annotation sequence** (from work-on.md — update this list when work-on.md adds new markers):

| Order | Marker | Completion Marker | Phase | |-------|--------|-------------------|-------| | 1 | `<!-- FORGE:INVESTIGATOR -->` | `<!-- INVESTIGATION:COMPLETE -->` | Phase 1: Investigation | | 2 | `<!-- FORGE:CONTRACT -->` | (none — standalone) | Phase 3C: Builder Contract | | 3 | `<!-- FORGE:CONTEXT -->` | `<!-- FORGE:CONTEXT:COMPLETE -->` | Phase 3C.5: Context | | 4 | `<!-- FORGE:ARCHITECT -->` | `<!-- FORGE:ARCHITECT:COMPLETE -->` | Phase 3C.6: Architecture | | 5 | `<!-- FORGE:BUILDER -->` | `<!-- FORGE:BUILDER:COMPLETE -->` | Phase 3M: Implementation | | 6 | `<!-- FORGE:REVIEW_STARTED -->` | (none — standalone) | Phase 5B: Review initiated | | 7 | `<!-- FORGE:TRAJECTORY -->` | (none — terminal) | Phase 7B: Trajectory log |

**Alternative path markers** (indicate non-standard outcomes):

| Marker | Meaning | |--------|---------| | `<!-- FORGE:DECOMPOSED -->` | Issue was decomposed into sub-issues | | `<!-- FORGE:DECOMPOSED:COMPLETE -->` | Decomposition completed cleanly | | `<!-- FORGE:GATE_FAILED -->` | Quality gate blocked the build | | `<!-- FORGE:PUSH_BLOCKED -->` | Branch push was blocked | | `<!-- FORGE:ANCESTRY_FAILED -->` | Post-commit ancestry audit failed |

**Classify each comment**:

# For each comment body, check for FORGE markers and completion markers
# Build an ordered map: marker → {present: bool, complete: bool, partial: bool, comment_id}

FOUND_INVESTIGATOR=false; INVESTIGATOR_COMPLETE=false
FOUND_CONTRACT=false
FOUND_CONTEXT=false; CONTEXT_COMPLETE=false; CONTEXT_PARTIAL=false
FOUND_ARCHITECT=false; ARCHITECT_COMPLETE=false; ARCHITECT_PARTIAL=false
FOUND_BUILDER=false; BUILDER_COMPLETE=false
FOUND_REVIEW_STARTED=false
FOUND_TRAJECTORY=false
FOUND_DECOMPOSED=false; DECOMPOSED_COMPLETE=false
FOUND_GATE_FAILED=false
FOUND_PUSH_BLOCKED=false
FOUND_ANCESTRY_FAILED=false

# Walk comments in order
echo "$COMMENTS" | jq -c '.[]' | while IFS= read -r comment; do
  BODY=$(echo "$comment" | jq -r '.body')
  COMMENT_ID=$(echo "$comment" | jq -r '.id')

  echo "$BODY" | grep -q "FORGE:INVESTIGATOR" && FOUND_INVESTIGATOR=true && \
    echo "$BODY" | grep -q "INVESTIGATION:COMPLETE" && INVESTIGATOR_COMPLETE=true

  echo "$
Read more
Ships withforgedock

ForgeDock — autonomous AI dev pipeline for Claude Code. GitHub as agent memory: issue in, PR out.

Get the whole plugin

Other commands on forgedock.