Skip to content
Back to skills

Feature Dev

BSecurity

Implement features following the approved PLAN.md and documented standards.

  • 8 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added November 5, 2026
developmenttypescriptpythonrustgoshellbashtestinggitapibackend

Works with

  • claude code
  • cursor
  • vscode
  • terminal
  • cli
  • api

Security analysis

B88/100
  • criticalSends environment variables or credentials to an external URL

Pro scans all 9 files and shows the line behind each finding

Scanned November 5, 2026

npx -y skills add nightgauge/nightgauge --skill feature-dev --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Feature Dev?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Feature Dev
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/nightgauge-feature-dev/badge)](https://www.skillsdirectory.com/skills/nightgauge-feature-dev)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: feature-dev
description: Implement features following the approved PLAN.md and documented standards.
  Includes quality review against docs/ files. Use after /feature-planning or
  when implementing any planned feature.
license: Apache-2.0
metadata:
  author: nightgauge
  version: "1.18.0"
  source: https://github.com/nightgauge/nightgauge
allowed-tools: Read Write Edit Glob Grep Bash Task
orchestration:
  mode: fanout
  phase: quality-review
  ceiling: fanout
  units:
    - id: code-quality
      role: reviewer
      promptRef: _includes/review-and-correction.md
    - id: security
      role: reviewer
      promptRef: _includes/review-and-correction.md
    - id: test
      role: reviewer
      promptRef: _includes/review-and-correction.md
    - id: documentation
      role: reviewer
      promptRef: _includes/review-and-correction.md
    - id: performance
      role: reviewer
      promptRef: _includes/review-and-correction.md
    - id: accessibility
      role: reviewer
      promptRef: _includes/review-and-correction.md
  judge:
    mode: merge
    quorum: 1
    promptRef: _includes/review-and-correction.md
# Note: disable-model-invocation prevents the skill from making direct LLM
# reasoning calls (e.g., free-form "think about X" prompts). Programmatic
# SDK/API calls via allowed-tools (Bash, Task, etc.) are still permitted.
# Completion verification is a Go StageGate (FeatureDevGate /
# FeatureValidateGate — internal/orchestrator/gates), NOT a Claude-only
# `hooks: Stop:` block: hooks silently never fired on non-Claude adapters
# (spike #33 D2, #55). Do not reintroduce hooks here — the portability
# linter rejects them.
inputs:
  - pipeline/planning-{N}.json
  - plans/{N}-*.md
outputs:
  - pipeline/dev-{N}.json
disable-model-invocation: true
---

## System Context

**Product**: Nightgauge — AI-powered Issue-to-PR pipeline.

**Architecture**: Three-layer stack: portable Skills (SKILL.md), a TypeScript
SDK, and a VSCode Extension, over a Go deterministic layer. Six pipeline
stages execute as isolated subagents with JSON context handoff files.

**Execution model**: Each pipeline stage runs in a fresh conversation. Context
is passed exclusively through JSON files in the clone's pipeline state
directory (`nightgauge layout path pipeline`) — never through conversation
history. Every stage reads its predecessor's context file
and writes its own.

**Configuration**: 6-tier config system — built-in defaults → global config →
project config → local config → env vars → CLI flags. Reference:
[docs/CONFIGURATION.md](https://github.com/nightgauge/nightgauge/blob/main/docs/CONFIGURATION.md).

**Standards**: Code standards in `docs/CODE_STANDARDS.md`. Security rules in
`standards/security.md`. Testing patterns in `docs/TESTING.md`. Git workflow in
`docs/GIT_WORKFLOW.md`.

**Critical rules**: Never push to main. Never hardcode secrets. Never downgrade
versions. Pre-submission validation is mandatory.

## Autonomy Contract

This run is autonomous. No human is watching, and nobody can answer a
question mid-stage. `AskUserQuestion` is disabled — and _behaving_ as if it
were available is the same failure.

- **Proceed without asking** for any reversible action that follows from the
  stage's task. If a decision is genuinely undecidable from the issue, the
  context files, and the repo, fail fast with a clear error — never pause to
  ask, and never silently pick between materially different product
  directions.
- **Never end a turn on a promise.** Before ending your turn, check your last
  paragraph: if it is a plan, a question, a list of next steps, or a promise
  about work not yet done ("I'll now…", "Next, I will…"), do that work now
  with tool calls instead of describing it. A turn that ends on stated intent
  with no corresponding tool call is recorded as a `premature_turn_end` stage
  failure, not a success.
- **Do not stop because the session feels long.** End the turn only when the
  stage's output contract is satisfied (its context file and phase markers
  are written) or you are genuinely blocked — and a genuine block is reported
  as an explicit failure, never as an open question.
- **Never end a turn with background work outstanding.** There is no "await
  and resume" — your turn ending IS stage completion, and the pipeline
  advances immediately. If you started something in the background, block on
  it and read its result before you finish. "I'll wait for that to complete
  rather than poll, and pick the pipeline back up once it lands" is not a
  handoff; it is the stage reporting success on work it never saw (#202).
- **Work only inside the worktree you were given.** Never delegate the
  stage's implementation to a subagent running under worktree isolation, and
  never `cd` outside your workspace to edit files. Only your own worktree is
  read by later stages: on #202 a subagent wrote the entire fix into
  `.claude/worktrees/agent-<id>`, so the stage passed, the branch stayed
  empty, and the work was invisible to every stage after it. A gate now fails
  the stage when this happens — but the run is dead either way, so do the work
  where you stand.


# Feature Development

> Implement features following approved plans and documented standards

## Description

This skill implements features by:

1. Reading the approved `PLAN.md` from `/feature-planning`
2. Reading knowledge base files (`PRD.md`, `decisions.md`) when `knowledge_path`
   is set
3. Following documented standards from `docs/`
4. Writing code, tests, and documentation
5. Running quality review against documented standards
6. Writing dev context for downstream validation
7. Generating E2E test suggestions for UI-touching changes and setting
   `includes_e2e` in dev context for downstream validation

## Invocation

| Tool           | Command                                |
| -------------- | -------------------------------------- |
| Claude Code    | `/nightgauge:feature-dev` (via plugin) |
| OpenAI Codex   | `$nightgauge-feature-dev`              |
| GitHub Copilot | Invoke via Agent Skills                |
| Cursor         | Invoke via Agent Skills                |

## Arguments

```bash
# Implement using PLAN.md from /feature-planning
/nightgauge-feature-dev

# Implement specific plan file
/nightgauge-feature-dev --plan "$(nightgauge layout path plans 42-photo-upload.md)"

# Force sequential implementation (disable parallel file creation)
/nightgauge-feature-dev --sequential

# Skip quality review (not recommended)
/nightgauge-feature-dev --skip-review
```

## Prerequisites

- **PLAN.md**: Should exist from `/feature-planning` (or provide one)
- **docs/ folder**: Used for standards compliance
- **Feature branch**: Should be on appropriate branch (from `/issue-pickup`)

## Philosophy

- **Plan-driven implementation** — Follow the approved plan exactly
- **Standards compliance** — Code must match docs/CODE_STANDARDS.md
- **Test-alongside** — Write tests as you implement, not after
- **Security-first** — Apply rules from docs/SECURITY.md automatically
- **Quality gates** — Review before committing
- **Observe before you mitigate** — no retry, fallback or widened tolerance for a
  mechanism nobody has seen (UNOBSERVED-MECHANISM RULE, below)
- **Parallel execution** — Independent files created simultaneously for faster
  implementation

## Spike Issues (`type:spike`)

For `type:spike` issues, the deliverable is a Markdown research artifact at
`docs/spikes/<N>-*.md` containing a `## Recommendations` section with a
fenced `yaml recommendations` block per
[docs/SPIKE_CONTRACT.md](https://github.com/nightgauge/nightgauge/blob/main/docs/SPIKE_CONTRACT.md). No production code
changes are expected. Author each recommendation with a stable kebab-case `id`
field — these ids are the idempotency key for the post-merge spike-materialize
stage.

---

## Configuration

This skill reads configuration from `.nightgauge/config.yaml`. See
[docs/CONFIGURATION.md](https://github.com/nightgauge/nightgauge/blob/main/docs/CONFIGURATION.md) for full schema reference.

| Config Key           | Default | Description                            |
| -------------------- | ------- | -------------------------------------- |
| `pipeline.auto_fix`  | `true`  | Auto-fix linting issues during feature |
| `commands.test`      | auto    | Test command override                  |
| `commands.lint`      | auto    | Lint command override                  |
| `commands.typecheck` | auto    | Type check command override            |
| `commands.build`     | auto    | Build command override                 |
| `project.number`     | -       | GitHub Project number for status sync  |

**Environment overrides:**

```bash
export NIGHTGAUGE_PIPELINE_AUTO_FIX=false
export NIGHTGAUGE_COMMANDS_TEST="pnpm test"
export NIGHTGAUGE_COMMANDS_LINT="pnpm lint"
```

---

## Input Contract

This skill requires `planning-{N}.json` (in the clone's pipeline state
directory, `nightgauge layout path pipeline`) from
`/nightgauge-feature-planning`.

**Schema**: See
[docs/CONTEXT_ARCHITECTURE.md](https://github.com/nightgauge/nightgauge/blob/main/docs/CONTEXT_ARCHITECTURE.md) for full
schema documentation.

---

## Supporting files (load on demand)

- `_includes/context-and-feedback-intake.md` (same directory as this SKILL.md) — read in Phases 0, 0.5, 0.7 (planning context, batch detection, feedback intake)
- `_includes/plan-knowledge-and-standards.md` (same directory as this SKILL.md) — read in Phases 1, 1.5, 1.6, 2 (plan verification, knowledge base, recall, standards)
- `_includes/implementation-and-testing.md` (same directory as this SKILL.md) — read in Phases 3, 4, 4.5, 4b (implementation, testing, E2E)
- `_includes/review-and-correction.md` (same directory as this SKILL.md) — read in Phases 5, 6, 6.5 (quality review, self-correction, feedback signals)
- `_includes/context-and-epilogue.md` (same directory as this SKILL.md) — read in Phases 7, 8, 9 (write dev context, sync board, output summary)

---

## Gotchas

- **Never run bare `vitest`.** Use the repository's documented test command in
  single-run mode (`vitest run`, scoped to the touched workspace) — bare
  `vitest` mis-resolves the workspace and can hang in watch mode.
- **Build before tests.** A build step MUST run before the suite — unit tests can
  pass while the build is broken, masking a defect feature-validate would catch
  later.
- **Never report success when a check failed (#2779).** Swallowing a failed
  build/test ships a broken change to pr-create where CI blocks the merge — fail
  loudly with the output instead.
- **Leave the changes on disk in THIS worktree (#202).** The gate now verifies
  with git, not with your `files_changed` report: a clean workspace whose branch
  is level with base fails the stage as `dev_produced_no_changes` no matter what
  the context file says. Both ways to trip it look like success from inside the
  stage — delegating the implementation to a worktree-isolated subagent, or
  ending the turn while a background command is still running.
- **UNOBSERVED-MECHANISM RULE (#1263)** — do not land a retry, a fallback, a
  widened timeout, or added tolerance for a failure whose mechanism you have not
  directly observed. Framing it as instrumentation does not exempt it: a
  redelivery retry shipped as "diagnostic" would have re-hidden the real bug the
  moment anyone fixed it, and a read-only probe shipped as "harmless" reported
  the exact opposite of the truth and cost the next session its entire duration.
  A diagnostic you add to a harness must be exercised against a known-good and a
  known-bad case before you trust a word it says; if that is impractical, do not
  ship it. Deliberate mitigation carries
  `NIGHTGAUGE-MITIGATION: issue=<owner/repo#N> mechanism=unobserved` beside the
  code, never prose in a doc comment. See
  [`_shared/UNOBSERVED_MECHANISM.md`](../_shared/UNOBSERVED_MECHANISM.md).
- **Never run the repo's full pre-submission suite here (#223).** `bash
scripts/ci-local.sh` and its equivalents belong to feature-validate, which is
  the stage that commits and pushes (#1608). `AGENTS.md`'s "run the complete local gate
  once before pushing" rule is scoped to pushing — you do not push. On #221 this stage spent
  the back half of its budget backgrounding, losing, polling for, and killing
  `ci-local.sh`, then ended its turn on `echo waiting-for-notification` having
  written a correct implementation it never handed off. Verify what you changed;
  the suite runs once, later, in the stage that owns it.
- See also the cross-cutting gotchas in
  [`_shared/GOTCHAS.md`](../_shared/GOTCHAS.md).

## Workflow

### Phase Marker Protocol

At the start of each phase, emit a structured phase marker as an HTML comment on
its own line. Format:

`<!-- phase:start name="{phase-name}" index={N} total={T} stage="feature-dev" -->`

This enables the orchestrator to track phase progress. Emit the marker BEFORE
any other output for that phase.

### SKIP_TO_PHASE Protocol

If the environment variable `SKIP_TO_PHASE` is set, skip all phases up to and
including the named phase. Begin execution from the NEXT phase after the one
specified. This enables retry-from-failed-phase without re-running completed
work.

**Detection:** Check `process.env.SKIP_TO_PHASE` at the start of each phase. If
the current phase name matches (case-insensitive, kebab-case), mark it as the
resume point and begin executing from the next phase.

**Example:** `SKIP_TO_PHASE=load-context` → skip phases 0 through load-context,
resume from the phase after load-context.

### Phase -1: Validate Environment

### Phase 0: Environment Preflight

**PURPOSE**: Verify the nightgauge binary is available and the environment
is healthy before executing any pipeline stage. Skills halt immediately with
actionable instructions when this check fails.

Three-layer check:

1. **Binary discovery** — shell-level, runs before invoking the binary
2. **Doctor check** — binary-level, full environment health via `doctor --json`
3. **Project environment** — the checks the project declares under
   `preflight.environment` (#101); opt-in, silent when none are declared

The binary discovery cascade below is **provider-neutral** (issue 4029): it works
identically under every adapter (Claude, Codex, Gemini, …) and references no
VSCode-extension-specific path. The host that spawns the skill (the VSCode
extension's `skillRunner`, or the Go `nightgauge` binary in auto/CLI mode)
resolves the binary authoritatively and exports `NIGHTGAUGE_BIN`, which
this cascade honors first. The remaining steps (PATH, the development-only repo
`bin/` and worktree canonical-repo `bin/`, `~/go/bin`) are fallbacks for direct
or terminal invocation.

This intentionally **diverges** from
`claude-plugins/nightgauge/hooks/lib/guard.sh` (issue 3262 → issue 4029): guard.sh is
Claude-Code-only and retains a trailing `~/.vscode/extensions/...` glob to serve
the standalone-terminal-Claude case (where no host exports `NIGHTGAUGE_BIN`).
Skills must stay portable Markdown and cannot reference that VSCode-only path —
so the shared resolution order (`NIGHTGAUGE_BIN` → PATH → gated repo → gated
canonical → `~/go/bin`) stays in sync, and only guard.sh carries the extra Claude-only
fallback. The `nightgauge preflight skill-portability` gate enforces that
no skill reintroduces a `.vscode/extensions` path, and that every cascade keeps
the `NIGHTGAUGE_DEV_REPO_BIN` gate (#2758): a foreign repository's
`bin/nightgauge` must never run.

After the cascade resolves `$BINARY`, the preflight prepends
`dirname($BINARY)` to `PATH` so subsequent bare `nightgauge ...`
invocations later in the same skill body resolve through PATH rather than
failing with "command not found" (issue 3262).

```bash
# Layer 1: provider-neutral binary discovery (NIGHTGAUGE_BIN → PATH → gated repo
# bin → gated canonical-repo bin → ~/go/bin). No VSCode-extension path — see issue 4029.
# Repo bins need NIGHTGAUGE_DEV_REPO_BIN=1 and a verified core checkout (#2758).
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"
if [ -z "$BINARY" ]; then
  echo "ERROR: nightgauge binary not found via NIGHTGAUGE_BIN, PATH or ~/go/bin" >&2
  echo "" >&2
  echo "Install via: go install github.com/nightgauge/nightgauge/cmd/nightgauge@latest" >&2
  echo "Or download from: https://github.com/nightgauge/nightgauge/releases" >&2
  echo "Run \`nightgauge doctor\` after installing to verify your environment." >&2
  exit 1
fi
# Make the resolved binary callable via bare `nightgauge ...` later in this skill body (issue 3262).
export PATH="$(dirname "$BINARY"):$PATH"

# Per-repo GitHub token: export GH_TOKEN so every `gh` call in this skill
# authenticates as the *current repo's* configured user instead of the machine-
# global `gh auth` active account. `forge auth token` resolves per-repo (config
# github_user/token → GITHUB_TOKEN → `gh auth token --user <github_user>`), so
# concurrent sessions/workspaces owned by different GitHub users each use their
# own token. GH_TOKEN outranks GITHUB_TOKEN and the gh keyring. Only resolve when
# unset (an upstream env value — e.g. the VSCode extension's terminal env —
# wins); never fail preflight over it. Mirrors hooks/lib/guard.sh (sync, issue 3262).
if [ -z "${GH_TOKEN:-}" ]; then
  IB_REPO_TOKEN="$("$BINARY" forge auth token 2>/dev/null || true)"
  if [ -n "$IB_REPO_TOKEN" ]; then
    export GH_TOKEN="$IB_REPO_TOKEN"
    export GITHUB_TOKEN="${GITHUB_TOKEN:-$IB_REPO_TOKEN}"
  fi
  unset IB_REPO_TOKEN
fi

# Layer 2: full environment health check via doctor --json
DOCTOR_RESULT=$("$BINARY" doctor --json 2>/dev/null)
DOCTOR_EXIT=$?
if [ "$DOCTOR_EXIT" -eq 2 ]; then
  echo "ERROR: Environment check failed — nightgauge doctor reports broken environment." >&2
  FAILED_CHECKS=$(printf '%s\n' "$DOCTOR_RESULT" | jq -r '.failed_checks[]? // empty' 2>/dev/null)
  if [ -n "$FAILED_CHECKS" ]; then
    echo "Failing check(s): $(echo "$FAILED_CHECKS" | tr '\n' ',' | sed 's/,$//')" >&2
  fi
  printf '%s\n' "$DOCTOR_RESULT" | jq -r '.errors[]' >&2 2>/dev/null || true
  INSTALL_MSG=$(printf '%s\n' "$DOCTOR_RESULT" | jq -r '.install_instructions // empty' 2>/dev/null)
  [ -n "$INSTALL_MSG" ] && echo "$INSTALL_MSG" >&2
  exit 1
fi
if [ "$DOCTOR_EXIT" -eq 1 ]; then
  echo "WARNING: Environment has non-critical issues:" >&2
  printf '%s\n' "$DOCTOR_RESULT" | jq -r '.warnings[]' >&2 2>/dev/null || true
  # Continue — warnings do not block skill execution
fi

# Layer 3: project-declared environment checks (preflight.environment, #101).
# Opt-in: with none declared this prints nothing and continues. The verb
# writes one `[environment-halt]` line per failed check, with its remedy.
if ! "$BINARY" preflight environment >/dev/null; then
  echo "[environment-halt] Project environment check failed — fix the environment, not the code." >&2
  exit 1
fi
```

**Exit codes from `nightgauge doctor`**:

| Code | Meaning                         | Skill behavior                          |
| ---- | ------------------------------- | --------------------------------------- |
| 0    | Healthy                         | Continue                                |
| 1    | Degraded (warnings only)        | Continue with warning printed to stderr |
| 2    | Broken (required checks failed) | Halt immediately with error details     |

**Layer 3** halts the stage when any check declared under
`preflight.environment` in the workspace's `.nightgauge/config.yaml` fails
(exit 1) or the declaration is invalid (exit 2). The failure is in the
operator's environment, not the code: do not edit code to work around it, do
not run the remedy yourself, and end the stage. The pipeline records it as
`environment_halt` and holds the issue for an operator.

Do not theorize about the cause beyond what is printed here — the failing
check name (`failed_checks`) and its `.errors[]` message are the complete
diagnosis (#277).


---

```bash
printf '<!-- phase:start name="validate-environment" index=0 total=17 stage="feature-dev" -->\n'
```

**PURPOSE**: Verify the skill is running in the correct repository before
loading context or doing any work.

### Repo Identity Assertion (HARD GATE — non-recoverable)

If the `NIGHTGAUGE_TARGET_REPO` environment variable is set, the orchestrator
has pinned the exact repo this stage must run in. Verify the current repository
matches **before doing any work**:

```bash
if [ -n "$NIGHTGAUGE_TARGET_REPO" ]; then
  # Derive this checkout's identity from its own git remote. The question
  # is "which repository is this working directory?", and the remote answers
  # it exactly — locally, with no API call. This used to shell out to the
  # GitHub CLI for the same string, spending a request per stage on every
  # repo in the workspace, invisible to `nightgauge api-usage`.
  ACTUAL_REPO=$(git remote get-url origin 2>/dev/null \
    | sed -E 's#^git@[^:]+:#-#; s#^https?://[^/]+/#-#; s#^-##; s#\.git$##')
  if [ -n "$ACTUAL_REPO" ] && [ "$ACTUAL_REPO" != "$NIGHTGAUGE_TARGET_REPO" ]; then
    echo "[repo-mismatch] FATAL: repository identity assertion failed"
    echo "  Expected: $NIGHTGAUGE_TARGET_REPO"
    echo "  Actual:   $ACTUAL_REPO"
    echo "  CWD:      $(pwd)"
    echo ""
    echo "The orchestrator expected this stage to run in $NIGHTGAUGE_TARGET_REPO"
    echo "but the working directory belongs to $ACTUAL_REPO."
    exit 1
  fi
fi
```

**This is a terminal, non-recoverable stop condition. If the check prints
`[repo-mismatch]` and exits 1, you MUST immediately end the stage with a failure.**

Specifically, on a mismatch you must NOT:

- `cd` into a different directory, switch worktrees, or `gh repo set-default` to
  "make it match" — the orchestrator owns CWD; second-guessing it corrupts state.
- Continue to later phases, create or push a branch, or open a PR — every
  downstream artifact would land in the wrong repo.
- Ask the user a question (`AskUserQuestion`) — autonomous runs have no human at
  the prompt; the question is auto-dismissed and you would proceed on a guess.
- Write a context/assessment file that claims success.

The correct and ONLY action is to stop now and let the stage exit non-zero. This
is a configuration fault in repo routing (the orchestrator set the wrong
`NIGHTGAUGE_TARGET_REPO` for this worktree); it is fixed upstream in the
orchestrator, never worked around inside the stage. The `[repo-mismatch]` marker
is how the pipeline classifies and surfaces it.

This check is a no-op — and the stage proceeds normally — when
`NIGHTGAUGE_TARGET_REPO` is unset (e.g. manual single-stage CLI
invocations) or already matches the current repo.


**Grounding gate (#4099)** — before loading context or editing anything, confirm
you are grounded: on **this** issue's feature branch (not the base) with the
issue context present. Closes the #3863 "am I on the right issue/branch?" gap.
ON by default (`pipeline.grounding_gate.enabled: false` disables it).

```bash
ISSUE_NUMBER="${NIGHTGAUGE_ISSUE_NUMBER:-$(git branch --show-current | sed -n 's#^[^/]*/\([0-9]*\)-.*#\1#p')}"
: "${ISSUE_NUMBER:?set NIGHTGAUGE_ISSUE_NUMBER or check out the issue branch}"
# Full PREFLIGHT.md discovery cascade (#55 — this block had diverged to a
# 3-rung variant, missing the canonical-repo and ~/go/bin fallbacks).
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"
if [ -n "$BINARY" ]; then
  "$BINARY" ground "$ISSUE_NUMBER" || {
    echo "GROUNDING FAILED — do NOT edit files. Switch to the issue's feature branch / re-run issue-pickup, or stop and surface the mismatch (#4099, #3863)."
    exit 1
  }
fi
```

When the gate prints `recommendation=pull-human` (grounded but no acceptance
criteria), pause and request the missing context rather than guessing the premise.

**Architecture-approval gate (#4098, #4135)** — a high-impact decision stays
human-owned: it must be approved by a human before feature-dev implements it. A
decision is high-impact when ANY of these hold: ≥2 distinct architectural
trade-off signals in the issue/ADR; a high-risk issue (`routing.risk_high`); a
dependency **major-version** bump (`dependency_analysis.major_bumps_count > 0`,
emitted by feature-planning); or a production-touching change
(`dependency_analysis.production_area`). The gate is **on by default** — set
`pipeline.architecture_approval.enabled: false` to turn it off. This is a hard
gate, **not** an auto-acceptable stage prompt — so it holds even under
`auto_accept_stages: true`.

```bash
ISSUE_NUMBER="${NIGHTGAUGE_ISSUE_NUMBER:-$(git branch --show-current | sed -n 's#^[^/]*/\([0-9]*\)-.*#\1#p')}"
: "${ISSUE_NUMBER:?set NIGHTGAUGE_ISSUE_NUMBER or check out the issue branch}"
if [ -n "$BINARY" ]; then
  "$BINARY" approval-gate "$ISSUE_NUMBER" || {
    echo "ARCHITECTURE APPROVAL REQUIRED — do NOT implement. A human must review the"
    echo "decision (the plan / decisions.md ADR) and add the approval label, or write"
    echo "{\"approved\": true} to approval-${ISSUE_NUMBER}.json with"
    echo "'nightgauge layout write pipeline approval-${ISSUE_NUMBER}.json'."
    exit 1
  }
fi
```

---

### Phase 0: Read Planning Context

```bash
printf '<!-- phase:start name="read-planning-context" index=1 total=17 stage="feature-dev" -->\n'
```

**PURPOSE**: Load context from previous pipeline stage.

> **Read `_includes/context-and-feedback-intake.md` (same directory as this SKILL.md) now and follow its instructions before continuing this phase.**

---

### Phase 0.7: Feedback Context Check

```bash
printf '<!-- phase:start name="feedback-context-check" index=2 total=17 stage="feature-dev" -->\n'
```

**PURPOSE**: Detect whether this is a retry run triggered by validate feedback
and load prior failure evidence so the agent avoids repeating the same mistakes.

> **Read `_includes/context-and-feedback-intake.md` (same directory as this SKILL.md) now and follow its instructions before continuing this phase.**

---

### Phase 1: Plan Verification

```bash
printf '<!-- phase:start name="plan-verification" index=3 total=17 stage="feature-dev" -->\n'
```

**PURPOSE**: Pre-load context files, locate and validate the plan, and confirm
branch alignment before implementing.

> **Read `_includes/plan-knowledge-and-standards.md` (same directory as this SKILL.md) now and follow its instructions before continuing this phase.**

---

#### Backstop: the issue is not pipeline work at all

feature-planning is supposed to catch this and stop before you are dispatched
(see its _Not-Pipeline-Actionable Signal_ section), but it can miss — and when
it does, you are the last stage that can end the run honestly.

If, having read the issue and the plan, the deliverable turns out to be
something **no agent can produce** — a sign-off reserved to a licensed
professional, an act only the operator can perform (rotate a credential, accept
terms, pay an invoice, provision hardware), a physical-world step, or a decision
that is the owner's to make — then there is no implementation to write, and
writing one anyway would be a fabrication dressed as progress.

**Stop here and declare it.** Do not implement, do not commit, and do not simply
end your turn with an explanation: prose in a final message is invisible to
every gate downstream. What the pipeline reads is the deliverable, so write
`dev-{N}.json` (`nightgauge layout write pipeline dev-{N}.json`) with empty
`files_changed` and this signal:

```json
{
  "files_changed": { "created": [], "modified": [], "deleted": [] },
  "feedback": [
    {
      "signal_type": "NOT_PIPELINE_ACTIONABLE",
      "emitted_by_stage": "feature-dev",
      "backtrack_target_stage": null,
      "severity": "blocking",
      "rationale": "<what the deliverable actually is, and why no code satisfies it>",
      "evidence": ["<quoted issue text or owner comment that establishes it>"]
    }
  ]
}
```

Ending the turn without this file is the failure mode that made #1241 worth
fixing. In the specimen run, feature-dev refused a privacy-policy legal review,
explained itself accurately and at length, and wrote nothing — so the gate saw
only an empty workspace, the deterministic fallback stamped a handoff claiming
six files it had picked up from a stale base ref, and the run was booked
`dev_produced_no_changes`: an agent-class failure that halted the whole
repository over a stage that had behaved correctly.

With the signal, the same refusal ends the run `blocked`: the finding is
persisted, the issue is commented and labelled `owner-action` so nothing
dispatches it again, its board row parks in Backlog, an Action Center card goes
to the operator, and no failure is charged to the issue or the pipeline.

**The bar is "no agent could produce this artifact"** — not "this is hard",
"the criteria are vague" (that is `ACCEPTANCE_CRITERIA_AMBIGUOUS`), or "this is
bigger than planned" (`COMPLEXITY_UNDERESTIMATED`).

@see Issue #1241

---

### Phase 1.5: Knowledge Base Read

```bash
printf '<!-- phase:start name="knowledge-base-read" index=4 total=17 stage="feature-dev" -->\n'
```

**PURPOSE**: When `knowledge_path` is set in the planning context (or issue
context), read the scaffolded knowledge files (`PRD.md`, `decisions.md`) to
pre-load requirements and design decisions before implementing. This ensures the
agent builds on prior knowledge rather than re-deriving it.

> **Read `_includes/plan-knowledge-and-standards.md` (same directory as this SKILL.md) now and follow its instructions before continuing this phase.**

---

### Phase 1.6: Recall Architectural Constraints

```bash
printf '<!-- phase:start name="recall-architectural-constraints" index=5 total=17 stage="feature-dev" -->\n'
```

**PURPOSE**: Query the knowledge recall index using the files being modified as
the search signal. When the codebase has recorded prior architectural decisions
that reference those files, inject them as an "Architectural Constraints" block
above the implementation prompt so the agent cannot inadvertently violate them.

> **Read `_includes/plan-knowledge-and-standards.md` (same directory as this SKILL.md) now and follow its instructions before continuing this phase.**

---

### Phase 2: Standards Loading

```bash
printf '<!-- phase:start name="standards-loading" index=6 total=17 stage="feature-dev" -->\n'
```

**PURPOSE**: Load code, security, and testing standards (with graceful greenfield
fallbacks) so implementation follows documented conventions.

> **Read `_includes/plan-knowledge-and-standards.md` (same directory as this SKILL.md) now and follow its instructions before continuing this phase.**

---

### Phase 3: Implementation

```bash
printf '<!-- phase:start name="implementation" index=7 total=17 stage="feature-dev" -->\n'
```

**PERFORMANCE**: This phase uses parallel execution when multiple independent
files need to be created. Files with dependencies are created sequentially after
their dependencies are complete.

> **Read `_includes/implementation-and-testing.md` (same directory as this SKILL.md) now and follow its instructions before continuing this phase.**

---

### Phase 4: Testing

```bash
printf '<!-- phase:start name="testing" index=8 total=17 stage="feature-dev" -->\n'
```

**PURPOSE**: Write unit tests, run a build-before-tests gate, run the suite,
check coverage, and fix failures.

> **Read `_includes/implementation-and-testing.md` (same directory as this SKILL.md) now and follow its instructions before continuing this phase.**

### Phase 4b: E2E Testing (Conditional)

```bash
printf '<!-- phase:start name="e2e-testing" index=9 total=17 stage="feature-dev" -->\n'
```

**PURPOSE**: Generate and, when a framework is configured (Playwright, Cypress,
Selenium), run end-to-end / integration tests for UI-touching changes; set
`INCLUDES_E2E` accordingly. Backend-only changes with no framework skip
gracefully.

> **Read `_includes/implementation-and-testing.md` (same directory as this SKILL.md) now and follow its instructions before continuing this phase.**

---

### Phase 5: Quality Review

```bash
printf '<!-- phase:start name="quality-review" index=10 total=17 stage="feature-dev" -->\n'
```

**PURPOSE**: Run the 6 reviewer units declared in this skill's `orchestration:`
frontmatter (code quality, security, test, documentation, performance,
accessibility), aggregate findings, and set the quality-check result variables.
On a provider with an orchestration capability the `WorkflowEngine` fans the six
units out concurrently and a judge unit merges their verdicts. Without one, this
phase reviews nothing and leaves `SECURITY_REVIEW_RESULT=skipped`: an author
reading its own diff is not a review, and feature-validate runs the independent
one. See
[docs/WORKFLOW_ORCHESTRATION.md](https://github.com/nightgauge/nightgauge/blob/main/docs/WORKFLOW_ORCHESTRATION.md).

> **Read `_includes/review-and-correction.md` (same directory as this SKILL.md) now and follow its instructions before continuing this phase.**

---

### Phase 6: Self-Correction

```bash
printf '<!-- phase:start name="self-correction" index=11 total=17 stage="feature-dev" -->\n'
```

**PURPOSE**: Address review findings, re-run tests, run the formatter, and pass
the Step 6.4 focused-check HARD GATE before proceeding.

**Step 6.4 — Verify Focused Checks Pass (HARD GATE)**: The build, the tests for
what changed and the formatter MUST pass before proceeding. These checks are
**blocking** — feature-dev MUST NOT report success if any of them fail.
Swallowing failures here lets a broken PR through to `pr-create`, where CI
catches it and blocks the merge. See issue #2779 for the incident that motivated
this gate. The repository's complete gate belongs to feature-validate (#2784).
The build must report `passed`, or `skipped` with no build system; a missing
status fails. The focused tests run under their own guarded command in Step 6.2.

> **Read `_includes/review-and-correction.md` (same directory as this SKILL.md) now and follow its instructions before continuing this phase.**

---

### Phase 6.5: Feedback Signal Evaluation

```bash
printf '<!-- phase:start name="feedback-signal-evaluation" index=12 total=17 stage="feature-dev" -->\n'
```

**PURPOSE**: Evaluate whether implementation encountered structural mismatches
between the plan and the actual codebase. Emit structured backward signals so
the orchestrator can route replanning to the right stage instead of committing a
fragile half-finished implementation.

> **Key principle**: Feedback signals are reserved for **upstream structural
> problems**. Minor adaptations (renaming a parameter, using an alternative
> method with the same purpose) do NOT warrant a signal. Ask: "Would a
> reasonable developer throw away the current approach and start over?"

> **Read `_includes/review-and-correction.md` (same directory as this SKILL.md) now and follow its instructions before continuing this phase.**

---

### Phase 7: Write Dev Context

```bash
printf '<!-- phase:start name="write-dev-context" index=13 total=17 stage="feature-dev" -->\n'
```

> **No commit or push in feature-dev.** Code is committed and pushed by
> `/nightgauge-feature-validate` after validation passes. This ensures only
> validated code reaches the remote branch and RALPH loop fixes are included.
> See Issue #1608. When routing SKIPS `feature-validate` (the fast-track
> trivial route), the commit is still made — by the compiled commit owner at
> the head of the `pr-create` deterministic runner (`stages.DecideCommit`,
> #1179), never by this stage.

**PURPOSE**: Write structured context file for downstream pipeline skills.

**CRITICAL**: This phase MUST execute before the output summary. Moving this
after the "IMPLEMENTATION COMPLETE" message causes the AI to stop executing
before the context file is written.

> **Read `_includes/context-and-epilogue.md` (same directory as this SKILL.md) now and follow its instructions before continuing this phase.**

---

### Phase 8: Sync Project Board Status

```bash
printf '<!-- phase:start name="sync-project-status" index=14 total=17 stage="feature-dev" -->\n'
```

Sync project board to "In progress" via Go binary `project sync-status`
(idempotent).

> **Read `_includes/context-and-epilogue.md` (same directory as this SKILL.md) now and follow its instructions before continuing this phase.**

---

### Phase 9: Output Summary

```bash
printf '<!-- phase:start name="output-summary" index=15 total=17 stage="feature-dev" -->\n'
```

Report implementation results: branch, files changed, quality check results,
context file path, and next step (`/nightgauge-feature-validate`).

> **Note**: No commit SHA is reported because code is not committed until
> feature-validate passes. The output summary should report files on disk, not a
> commit.

> **Read `_includes/context-and-epilogue.md` (same directory as this SKILL.md) now and follow its instructions before continuing this phase.**

---

## Output Contract

This skill outputs:

1. **Code changes** - Committed to feature branch
2. **`dev-{N}.json`** (written with `nightgauge layout write pipeline`) -
   Structured context for pipeline

**Schema**: See
[docs/CONTEXT_ARCHITECTURE.md](https://github.com/nightgauge/nightgauge/blob/main/docs/CONTEXT_ARCHITECTURE.md) for full
schema documentation.

**Next stage**: `/nightgauge-feature-validate`

---

### Phase 10: Self-Assessment Epilogue

```bash
printf '<!-- phase:start name="self-assessment" index=16 total=17 stage="feature-dev" -->\n'
```

### Self-Assessment Epilogue

**PURPOSE**: Evaluate whether this skill's instructions matched reality during
this execution. This phase is **non-blocking** — skip entirely if any main phase
failed. A perfectly working skill produces **no output** from this phase.

> See [docs/SKILL_SELF_ASSESSMENT.md](https://github.com/nightgauge/nightgauge/blob/main/docs/SKILL_SELF_ASSESSMENT.md) for
> the full strategy, synthesis algorithm, and integration architecture.

#### When to Skip

- Any prior phase exited with an error before completing
- The skill was cancelled or timed out
- Running in `--dry-run` mode

#### Step 1: Evaluate Execution Friction

Review the execution that just completed. Answer these questions honestly:

1. **Command failures**: Did any command, script, or binary call in the skill
   instructions fail? (e.g., script not found, wrong flags, missing binary)
2. **Workarounds**: Did you have to deviate from the skill instructions to
   accomplish the goal? (e.g., used `gh` directly because a referenced script
   didn't exist, skipped a step that referenced a nonexistent file)
3. **Stale references**: Did any file path, function name, API endpoint, or tool
   referenced in the instructions not exist in the current codebase?
4. **Unclear instructions**: Were any instructions ambiguous enough that you had
   to guess at the intended behavior?
5. **Missing instructions**: Was there a significant step you had to figure out
   on your own that should have been documented in this skill?

**If ALL answers are "no" — write nothing and complete the skill normally.** The
goal is silence when everything works.

#### Step 2: Write Assessment Record

Only if friction was detected in Step 1. Write a single JSON file,
`assessments/{STAGE_NAME}-${ISSUE_NUMBER}.json` in the clone's pipeline state
directory, through the binary (JSON on stdin; never a direct file write):

```bash
ISSUE_NUMBER="${NIGHTGAUGE_ISSUE_NUMBER:-$(git branch --show-current | sed -n 's#^[^/]*/\([0-9]*\)-.*#\1#p')}"
: "${ISSUE_NUMBER:?set NIGHTGAUGE_ISSUE_NUMBER or check out the issue branch}"
nightgauge layout write pipeline "assessments/{STAGE_NAME}-${ISSUE_NUMBER}.json" <<'JSON'
{ ... the record below ... }
JSON
```

The assessment record MUST follow this schema:

```json
{
  "schema_version": "1",
  "skill": "{STAGE_NAME}",
  "skill_file": "skills/nightgauge-{STAGE_NAME}/SKILL.md",
  "issue_number": 42,
  "timestamp": "2026-03-10T14:30:00Z",
  "friction": [
    {
      "type": "command_failure",
      "severity": "high",
      "description": "hooks/lib/add-to-project.sh not found — script was deleted",
      "skill_line_hint": "claude-plugins/nightgauge/hooks/lib/add-to-project.sh <issue-number>",
      "actual_resolution": "Used gh api graphql to add issue to project board directly",
      "suggested_fix": "Replace with: nightgauge project add <issue-number>"
    }
  ]
}
```

**Friction types**: `command_failure`, `workaround`, `stale_reference`,
`unclear_instruction`, `missing_instruction`

**Severity levels**:

- `high` — instruction is **broken**. Required manual workaround to complete.
- `medium` — instruction is **misleading**. Agent adapted without user help.
- `low` — instruction is **suboptimal**. No functional impact.

**Rules**:

- **One record per execution** — multiple friction items go in the `friction`
  array, not separate files.
- **Be specific** — quote the exact instruction text that was wrong. Not "some
  commands didn't work" but "Step 5.2 calls `hooks/lib/add-to-project.sh` but
  this script was deleted in commit 65915701."
- **Suggest the fix** — every finding MUST include `suggested_fix` with the
  concrete SKILL.md change needed. Not "update the docs" but "replace
  `hooks/lib/add-to-project.sh <N>` with `nightgauge project add <N>`."
- **Don't invent friction** — only report issues you actually encountered during
  this execution. Do not speculate about potential problems.

#### Step 3: Validate and Complete

```bash
# Validate JSON if written
ISSUE_NUMBER="${NIGHTGAUGE_ISSUE_NUMBER:-$(git branch --show-current | sed -n 's#^[^/]*/\([0-9]*\)-.*#\1#p')}"
: "${ISSUE_NUMBER:?set NIGHTGAUGE_ISSUE_NUMBER or check out the issue branch}"
ASSESSMENT_FILE="$(nightgauge layout path pipeline "assessments/{STAGE_NAME}-${ISSUE_NUMBER}.json")"
if [ -f "$ASSESSMENT_FILE" ]; then
  python3 -m json.tool "$ASSESSMENT_FILE" > /dev/null 2>&1 || \
    echo "WARNING: Assessment record is not valid JSON" >&2
fi
```


---

## Error Handling

| Condition             | Action                                                                         |
| --------------------- | ------------------------------------------------------------------------------ |
| Tests failing         | Show failing test output, fix implementation, re-run until pass                |
| Security issue found  | Auto-fix validated input/secrets issues, block commit until resolved           |
| Plan mismatch         | Continue with modified approach if reasonable, otherwise fail with explanation |
| Context file missing  | Exit 1 with error listing expected pipeline order                              |
| Parallel exec failure | Fall back to sequential implementation                                         |

Files in this skill

  • CHANGELOG.md9.1 KB
  • SKILL.md43.5 KB
  • _includes/context-and-epilogue.md11.4 KB
  • _includes/context-and-feedback-intake.md12.4 KB
  • _includes/implementation-and-testing.md18.2 KB
  • _includes/plan-knowledge-and-standards.md18 KB
  • _includes/review-and-correction.md18 KB
  • _overlays/claude-fable-5-1.md463 B
  • _profiles/compact.md25.2 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.