Back to skills
SKILL.md
Nightgauge Assess Epic
ASecurityAnalyze an epic's sub-issues and recommend batch vs sequential pipeline
- 8 stars
- 0 votes
- 0 copies
- 0 views
- Added November 5, 2026
Works with
Security analysis
100/100npx -y skills add nightgauge/nightgauge --skill nightgauge-assess-epic --agent claude-codeAre you the author of Nightgauge Assess Epic?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/nightgauge-nightgauge-assess-epic)---
name: nightgauge-assess-epic
description: Analyze an epic's sub-issues and recommend batch vs sequential pipeline
processing strategy. Use before starting work on an epic to determine optimal
execution approach.
license: Apache-2.0
metadata:
author: nightgauge
version: "1.0.2"
source: https://github.com/nightgauge/nightgauge
chainable: true
allowed-tools: Read Bash Glob Grep
---
# Nightgauge Assess Epic
## Description
Analyzes an epic's sub-issues to determine whether they should be processed via
batch, sequential, or hybrid pipeline execution. Extracts file overlap, size
variance, and dependency signals from sub-issues, then computes a deterministic
strategy recommendation with confidence scoring and estimated savings.
The recommendation is advisory: every sub-issue still runs its own pipeline and
PR into the epic branch, and `epic-complete` opens the single epic PR. There is
no multi-issue pipeline run (#366).
**Use Cases:**
- Planning pipeline execution strategy before starting an epic
- Evaluating whether sub-issues have sufficient file overlap for batching
- Estimating token and cost savings from parallel batch execution
- Identifying dependency chains that require sequential processing
**When to Use:**
- Before queuing an epic for pipeline processing
- When an epic has 3+ sub-issues and you want to optimize execution
- After sub-issues change (new issues added, scope changes) to refresh strategy
- When deciding the order in which to queue an epic's sub-issues
## Invocation
| Tool | Command |
| ----------- | --------------------------------------- |
| Claude Code | `/nightgauge:assess-epic <epic-number>` |
| Copilot | Invoke via Agent Skills extension |
| Cursor | Run via Agent Skills or direct SKILL.md |
| Headless | `claude -p "/nightgauge:assess-epic"` |
## Arguments
| Argument | Description | Required | Default |
| --------------- | ------------------------------- | -------- | ------- |
| `<epic-number>` | GitHub issue number of the epic | Yes | - |
### Examples
```bash
# Assess epic #799's execution strategy
/nightgauge:assess-epic 799
# Assess a different epic
/nightgauge:assess-epic 1672
```
---
## Prerequisites
- `gh` CLI installed and authenticated (`gh auth login`)
- `jq` installed for JSON processing
- Epic issue must exist with the `type:epic` label
- Sub-issues must be linked via GitHub's native sub-issue feature (GraphQL
`subIssues` API)
- Git repository with GitHub remote
**CRITICAL**: This skill runs headless. Do NOT use AskUserQuestion. Make
autonomous decisions or fail with clear error.
---
## Workflow
### Phase 0: Environment Preflight
<!-- include: ../_shared/PREFLIGHT.md -->
---
### Phase 1: Validate Input and Fetch Epic
#### Step 1.1: Validate Epic Number
```bash
EPIC_NUMBER="${1:?ERROR: Epic number is required. Usage: /nightgauge:assess-epic <epic-number>}"
# Validate numeric input
if ! printf '%s\n' "$EPIC_NUMBER" | grep -qE '^[0-9]+$'; then
echo "ERROR: Epic number must be a positive integer (got: $EPIC_NUMBER)"
exit 1
fi
```
#### Step 1.2: Fetch Epic Issue
```bash
EPIC_JSON=$(gh issue view "$EPIC_NUMBER" --json number,title,labels,state,body 2>&1)
if [ $? -ne 0 ]; then
echo "ERROR: Could not fetch issue #$EPIC_NUMBER. Verify the issue exists."
echo " Try: gh issue view $EPIC_NUMBER"
exit 1
fi
# Verify it has the type:epic label
IS_EPIC=$(printf '%s\n' "$EPIC_JSON" | jq -r '.labels[]?.name' | grep -c '^type:epic$' || echo "0")
if [ "$IS_EPIC" -eq 0 ]; then
echo "ERROR: Issue #$EPIC_NUMBER does not have the 'type:epic' label."
echo " This command only works on epic issues."
exit 1
fi
EPIC_TITLE=$(printf '%s\n' "$EPIC_JSON" | jq -r '.title')
echo "Epic #$EPIC_NUMBER: $EPIC_TITLE"
```
#### Step 1.3: Fetch Sub-Issues
The shared epic-handling reference, `skills/_shared/EPIC_HANDLING.md`, covers
sub-issue detection (read it directly — `assess-epic` is not a pipeline stage,
so the composer does not expand the directive below).
<!-- include: ../_shared/EPIC_HANDLING.md -->
The binary reads every sub-issue, page by page, or exits non-zero; it never
returns part of the list as the whole of it (#1701).
```bash
# Detect owner/repo from git remote
REMOTE_URL=$(git remote get-url origin 2>/dev/null)
OWNER=$(echo "$REMOTE_URL" | sed -E 's|.*[:/]([^/]+)/([^/.]+)(\.git)?$|\1|')
REPO=$(echo "$REMOTE_URL" | sed -E 's|.*[:/]([^/]+)/([^/.]+)(\.git)?$|\2|')
BINARY="${NIGHTGAUGE_BIN:-}"
[ -n "$BINARY" ] && [ ! -x "$BINARY" ] && BINARY=""
[ -z "$BINARY" ] && BINARY=$(command -v nightgauge 2>/dev/null || echo "")
if [ -z "$BINARY" ] && [ "${NIGHTGAUGE_DEV_REPO_BIN:-}" = "1" ]; then
for NG_ROOT in "$(git rev-parse --show-toplevel 2>/dev/null)" \
"$(cd "$(git rev-parse --git-common-dir 2>/dev/null)/.." 2>/dev/null && pwd)"; do
[ -x "$NG_ROOT/bin/nightgauge" ] || continue
grep -qx 'module github.com/nightgauge/nightgauge' "$NG_ROOT/go.mod" 2>/dev/null || continue
NG_ORIGIN="$(git -C "$NG_ROOT" config --get remote.origin.url 2>/dev/null)"
case "${NG_ORIGIN%.git}" in
git@github.com:nightgauge/nightgauge | https://github.com/nightgauge/nightgauge | \
ssh://git@github.com/nightgauge/nightgauge) BINARY="$NG_ROOT/bin/nightgauge"; break ;;
esac
done
fi
[ -z "$BINARY" ] && [ -x "$HOME/go/bin/nightgauge" ] && BINARY="$HOME/go/bin/nightgauge"
[ -n "$BINARY" ] && export PATH="$(dirname "$BINARY"):$PATH"
if [ -z "$BINARY" ]; then
echo "ERROR: nightgauge binary not found via NIGHTGAUGE_BIN, PATH or ~/go/bin"
echo "Install via: go install github.com/nightgauge/nightgauge/cmd/nightgauge@latest"
exit 1
fi
# stdout only: a warning on stderr must not land in the JSON.
if ! SUB_ISSUES_JSON=$("$BINARY" issue list --epic "$EPIC_NUMBER" \
--owner "$OWNER" --repo "$REPO" --json); then
echo "ERROR: Failed to fetch sub-issues for epic #$EPIC_NUMBER (the error is above)"
exit 1
fi
# The binary writes subIssues as null when there are none.
SUB_COUNT=$(printf '%s\n' "$SUB_ISSUES_JSON" | jq '.subIssues // [] | length')
if [ "$SUB_COUNT" -eq 0 ]; then
echo "ERROR: Epic #$EPIC_NUMBER has no sub-issues linked via GitHub's sub-issue feature."
echo " Sub-issues must be linked using the addSubIssue GraphQL mutation."
echo " Body text references (e.g., '- [ ] #123') do NOT count."
exit 1
fi
echo "Found $SUB_COUNT sub-issues"
printf '%s\n' "$SUB_ISSUES_JSON" | jq -r '.subIssues[] |
" #\(.number) - \(.title) [\(.state)]"'
```
---
### Phase 2: Assess with Go Binary (Deterministic)
`$BINARY` is the binary Step 1.3 resolved.
```bash
ASSESS_JSON=$("$BINARY" epic assess "$EPIC_NUMBER" \
--owner "$OWNER" --repo "$REPO" --json 2>/dev/null)
if [ $? -ne 0 ] || [ -z "$ASSESS_JSON" ]; then
echo "ERROR: nightgauge epic assess failed for epic #$EPIC_NUMBER"
exit 1
fi
STRATEGY=$(printf '%s\n' "$ASSESS_JSON" | jq -r '.strategy')
REASONING=$(printf '%s\n' "$ASSESS_JSON" | jq -r '.reasoning')
EST_COST=$(printf '%s\n' "$ASSESS_JSON" | jq -r '.estimatedCostUsd')
EST_MINUTES=$(printf '%s\n' "$ASSESS_JSON" | jq -r '.estimatedMinutes')
OPEN_COUNT=$(printf '%s\n' "$ASSESS_JSON" | jq '.issues | length')
echo "Strategy: $(echo "$STRATEGY" | tr '[:lower:]' '[:upper:]')"
echo "Reasoning: $REASONING"
```
---
### Phase 4: Generate Report
#### Step 4.1: Format Assessment Output
```bash
echo ""
echo "Epic #$EPIC_NUMBER Assessment"
echo "===================="
echo ""
echo "Strategy: $(echo "$STRATEGY" | tr '[:lower:]' '[:upper:]')"
echo "Reasoning: $REASONING"
echo ""
echo "Sub-Issues: $OPEN_COUNT open / $SUB_COUNT total"
echo ""
echo "Estimates:"
echo " Cost: \$$EST_COST"
echo " Time: $EST_MINUTES min"
echo ""
echo "Per-Issue Breakdown:"
printf '%s\n' "$ASSESS_JSON" | jq -r '.issues[] |
" #\(.issueNumber) complexity=\(.complexityScore) model=\(.recommendedModel)\(if .hasDependencies then " [blocked]" else "" end)"'
echo ""
echo "Recommendation:"
case "$STRATEGY" in
parallel)
echo " All $OPEN_COUNT sub-issues are independent — queue them concurrently."
;;
mixed)
echo " Queue independent sub-issues concurrently."
echo " Run dependency-blocked issues sequentially after their blockers."
;;
sequential)
echo " Process sub-issues one at a time in dependency order."
echo " High dependency complexity makes batching counterproductive."
;;
esac
```
#### Step 4.2: Write JSON Report
```bash
REPORT_FILE=$(printf '%s\n' "$ASSESS_JSON" | jq \
--arg epic_number "$EPIC_NUMBER" \
--arg epic_title "$(echo "$EPIC_TITLE" | sed 's/"/\\"/g')" \
--argjson sub_total "$SUB_COUNT" \
--arg assessed_at "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
'. + {
"schema_version": "2",
"epic_number": ($epic_number | tonumber),
"epic_title": $epic_title,
"sub_issues": { "total": $sub_total, "open": (.issues | length) },
"assessed_at": $assessed_at
}' | nightgauge layout write pipeline "epic-assessment-${EPIC_NUMBER}.json")
echo ""
echo "Report written to: $REPORT_FILE"
```
---
### Self-Assessment Epilogue
<!-- include: ../_shared/SELF_ASSESSMENT_EPILOGUE.md -->
---
## Error Handling
| Condition | Action |
| ----------------------------- | -------------------------------------------- |
| Missing epic number argument | Error with usage hint |
| Invalid epic number (non-int) | Error with validation message |
| Epic issue not found | Error with GitHub issue link suggestion |
| Issue lacks `type:epic` label | Error explaining epic requirement |
| No sub-issues linked | Error explaining GraphQL linking requirement |
| All sub-issues closed | Exit 0 with "no assessment needed" message |
| `gh` CLI not authenticated | Error with `gh auth login` instructions |
| GraphQL query failure | Error with raw response for debugging |
| `bc` not available | Fall back to integer arithmetic |
| Sub-issue body fetch failure | Continue with partial data, warn user |
---
## Pipeline Position
```
UTILITIES (not part of main pipeline)
/nightgauge:assess-epic <epic-number>
|
Standalone analysis tool for epic batch planning
Reads: GitHub API (epic + sub-issues + blocking)
Writes: pipeline/epic-assessment-{N}.json (nightgauge layout write)
```
This is a standalone utility skill. It does not affect pipeline state and can be
run at any time without interfering with active pipeline runs. The queue command
(`/nightgauge:queue`) automatically invokes this assessment when an epic
issue number is queued.
---
## Related Skills
- **`/nightgauge:queue`** - Queue management; auto-invokes assess-epic when
epic issues are queued
- **`skills/_shared/EPIC_HANDLING.md`** - Shared epic detection and handling
patterns
- **`skills/_shared/DEPENDENCY_CHECKING.md`** - Shared dependency checking logic
---
**Author:** nightgauge **License:** Apache-2.0
Attribution
Comments
Loading comments…
Newsletter
Get the weekly list of safe new skills, and the ones we pulled.