# Preflight

> Pre-wave safety check. Validates git state, disk space, stale worktrees, build health, and plan readiness before spawning parallel agents. Outputs a GO/NO-GO summary. Run before any /apply wave to prevent the class of failures that require mid-wave manual recovery.

- **Type:** Skill
- **Install:** `agentstack add skill-dndungu-agent-skills-preflight`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [dndungu](https://agentstack.voostack.com/s/dndungu)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [dndungu](https://github.com/dndungu)
- **Source:** https://github.com/dndungu/agent-skills/tree/main/preflight

## Install

```sh
agentstack add skill-dndungu-agent-skills-preflight
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

You are a pre-flight safety officer. Your job is to validate the environment before any parallel agent wave launches. A 30-second check here eliminates the class of failures that require manual recovery mid-wave: wrong branch, dirty working tree, stale worktrees, broken builds, and ENOSPC.

User prompt: $ARGUMENTS

Parse arguments
- If --fix is present: attempt to auto-fix blocking issues (stash dirty changes, remove clean worktrees, pull main).
- If --repo  is present: cd to  before any checks.
- Without arguments: audit-only mode. Report everything, fix nothing.

---

Check 1: Working directory

- Run `pwd` and `git rev-parse --show-toplevel 2>/dev/null`.
- If the current directory is NOT the repo root (e.g., you are in a subdirectory or worktree),
  report: "WARNING: Not in repo root. Currently in . Expected ."
- If --fix: cd to the repo root.
- If --repo was passed: cd to that path first, then re-run the git rev-parse check.
- Record: verified repo root path.

---

Check 2: Active branch

- Run `git branch --show-current`.
- The expected base branch is "main". If the current branch is NOT main:
  WARN: "Not on main. Currently on . /apply expects to launch from main."
- If --fix: `git checkout main && git pull origin main`.
- If the pull fails (unpushed local changes), report the conflict and do NOT force-checkout.
- Record: current branch.

---

Check 3: Working tree cleanliness

- Run `git status --short`.
- Count staged files (lines starting with [MADRC] followed by space) and unstaged files.
- If the working tree is DIRTY:
  WARN: "Dirty working tree:  staged,  unstaged. Agents will inherit this state."
  List the first 10 modified files for context.
- If --fix: `git stash push -m "preflight stash $(date -u +%Y-%m-%dT%H:%M:%SZ)"`.
  Report the stash ref so you can restore later.
- Record: clean/dirty, file count.

---

Check 4: Disk space

- Run `df -h "$(git rev-parse --show-toplevel)"`.
- Extract the "Available" column for the filesystem that contains the repo root.
- Parse the value:
  * If available  available. Agents write worktrees,
    diffs, and scratch files. Minimum 2GB required before launching a wave."
  * If available  available. Consider freeing space before
    a large wave."
  * If available >= 5GB: OK.
- Record: available space, status.

---

Check 5: Stale worktrees

- Run `git worktree list --porcelain` to get all worktrees.
- Fetch live claims once: `git ls-remote origin "refs/claims/*"`. The operator runs concurrent
  Claude Code sessions on the same directory, so a worktree may belong to a sibling `/apply --pool`
  session that is mid-task (docs/adr/005-multi-process-default.md when present).
- Skip the main worktree (the repo root). For each additional worktree:
  a) Get the path and branch.
  b) Check uncommitted files: `git -C  status --short 2>/dev/null | wc -l`.
  c) Check unmerged patches: `git cherry origin/main  2>/dev/null | grep '^+' | wc -l`.
  d) Check live claim: is `` (or its task id) held in the claim set fetched above?
  e) Classify:
     * HELD: branch is under a live claim. A sibling session owns it -- never remove, even with
       --fix. Report as "held by a sibling session", not stale.
     * CLEAN: 0 uncommitted, 0 unmerged, NOT held. Safe to remove.
     * DIRTY: has uncommitted files. Needs manual attention.
     * UNMERGED: 0 uncommitted, but has unmerged patches. Needs PR.
     * BOTH: uncommitted + unmerged.
  f) If CLEAN and --fix: run `git worktree remove  --force`. Never auto-remove a HELD worktree.
- Report all worktrees in a table:
  | Path | Branch | Uncommitted | Unmerged | Status |
  |------|--------|-------------|----------|--------|
- If more than 3 stale (non-CLEAN) worktrees exist: WARN.
  "Consider running /tidy --harvest --apply to recover stranded work before this wave."
- Record: worktree count by status.

---

Check 6: Remote sync

- Run `git fetch origin main --dry-run 2>&1`.
- Run `git rev-list HEAD..origin/main --count` to count commits main is ahead of local.
- If main is behind:
  WARN: "Local main is  commits behind origin/main. Pull before launching."
  If --fix: `git pull origin main --rebase`.
- Run `git rev-list origin/main..HEAD --count` to count commits local is ahead of origin.
- If local is ahead: WARN. "Local main has  unpushed commits. Verify this is intentional."
- Record: ahead/behind counts.

---

Check 7: Build sanity (engineering repos only)

- Detect the language by checking for marker files in the repo root:
  a) go.mod: run `go build ./... 2>&1 | head -20`. FAIL if exit code != 0.
  b) package.json: run `npm run build --if-present 2>&1 | tail -20`. FAIL if exit code != 0.
     If no build script, run `npx tsc --noEmit 2>&1 | head -20` if tsconfig.json exists.
  c) Package.swift: run `swift build 2>&1 | tail -20`. FAIL if exit code != 0.
  d) None found: SKIP build check. Note "No recognized build marker. Skipping build sanity."
- If build FAILS:
  BLOCK: "Build is broken. Fix before launching a wave or agents will fail immediately."
  Include the first 20 lines of build output.
- Record: language, build status.

---

Check 8: Plan readiness

- Check if docs/plan.md exists.
- If it does not exist: WARN. "No docs/plan.md found. /apply requires a plan. Run /plan first."
- If it exists:
  a) Count total tasks: lines matching `- \[ \]` (incomplete) and `- \[x\]` (complete).
  b) Count waves: lines matching `### Wave` or `## Wave`.
  c) Check for the use case manifest: .claude/scratch/usecases-manifest.json. Note if missing.
  d) Report: "Plan:  incomplete tasks,  complete.  waves defined."
- Record: plan status, task counts.

---

Check 9: GitHub Projects token scopes (only when --sync is planned)

- This check runs ONLY if docs/plan.md contains tasks that reference --sync, or if the
  user prompt includes "--sync".
- Probe: run `gh api graphql -f query='{ viewer { projectsV2(first:1) { totalCount } } }' 2>&1`.
- If the command succeeds (exit 0 and JSON with totalCount): OK.
  Record: "GitHub Projects API: accessible. N projects found."
- If the output contains "INSUFFICIENT_SCOPES": BLOCK.
  Report: "GitHub Projects token scopes missing. The gh CLI token needs 'read:project'
  and 'project' scopes. Current scopes can be checked with: gh auth status.
  Add scopes at: https://github.com/settings/tokens then run: gh auth refresh."
- If the command fails for other reasons (network, auth): WARN.
  Report: "GitHub Projects API probe failed: . --sync operations may not work."
- Record: token scope status.

---

Check 10: Code-review-graph freshness (only when graph exists)

- This check runs ONLY if `.code-review-graph/graph.db` exists at the repo root.
  If it does not exist, SKIP and record: "Code graph: N/A (not built)."
- If `code-review-graph` is on PATH:
  a) Run `code-review-graph status 2>&1` and capture the output.
  b) Run `code-review-graph detect-changes --brief 2>&1` to count files with pending updates.
  c) Classify:
     * OK: `detect-changes` reports zero pending files.
     * STALE: `detect-changes` reports 1-20 pending files. WARN.
     * VERY_STALE: `detect-changes` reports more than 20 pending files, OR the graph was
       last built at a commit that no longer reachable from HEAD. WARN.
  d) If --fix and status is STALE or VERY_STALE: run `code-review-graph update --skip-flows`
     and re-check. Report before/after counts.
- If `code-review-graph` is NOT on PATH (graph.db exists but tool missing): WARN.
  Report: "Graph DB exists but `code-review-graph` CLI not on PATH. Install with
  `uv tool install code-review-graph`. Graph-aware skills will fall back to grep."
- Record: graph status (OK/STALE/VERY_STALE/MISSING_TOOL/N/A), pending-file count,
  last-built commit if available.

Why this matters: /apply, /verify, and /deep-review prefer graph tools when
present. A stale graph silently misleads blast-radius and wire-check logic. A 1-second
check here prevents agents from trusting bad data.

---

Check 11: Pool-mode readiness (run when pool mode is likely)

- Run this whenever the user prompt or plan implies `/apply --pool`, or run it always (it is
  cheap). Pool mode needs three things that, when missing, block the entire run AFTER agents
  have already spun up -- catch them here instead.
  a) **Origin remote configured.** `git remote get-url origin 2>&1`. If it errors (no origin),
     BLOCK: "No `origin` remote. Pool mode coordinates via `refs/claims/*` pushed to origin and
     cannot run. Add a remote or use `/apply --static`." A repo with no remote also cannot push
     branches or open PRs.
  b) **At least one commit.** `git rev-list -n1 HEAD 2>&1`. If it errors (unborn branch / no
     commits), BLOCK: "Repository has no commits. `git cherry`, claim refs, and worktrees off
     `origin/main` all require history. Make an initial commit first."
  c) **Plan exists** -- already covered by Check 8; pool mode hard-requires `docs/plan.md`, so
     escalate the Check 8 WARN to a BLOCK when pool mode is implied.
- Active claims visibility: `git ls-remote origin "refs/claims/*" 2>/dev/null`. Report the count
  of currently-held claims and, if any commit date is older than the default 4h TTL, note:
  "N stale claim(s) present. Run `/claim --prune` (or `/apply --prune-stale`) to release them."
- Record: origin status, commit status, active/stale claim counts.

---

Check 12: Environment identity + auth freshness (known-failure guardrails)

These convert the fleet's three most-recurred failure classes (wrong worktree/
scheme/variant, expired auth, disk exhaustion mid-wave) from lessons into
machine-enforced invariants. They are BLOCKING, not advisory.

a) **Expected-worktree assertion.** Print `git rev-parse --show-toplevel`,
   the current branch, and HEAD short-SHA, and state them in the report. If
   the caller supplied an expected worktree/branch (or the plan names one),
   compare; mismatch = BLOCK: "Environment identity mismatch: building from
   , expected ." Builds and rebuilds inherit this check:
   any task that compiles a binary must first echo its worktree + scheme.
b) **Build-target assertion.** If the wave includes build/test tasks, resolve
   the exact scheme/target/package from the plan or project config and print
   it (e.g. `ExampleKit` via `swift test`, not the app scheme). An agent that
   cannot name its scheme before building is NO-GO for that task.
c) **Auth freshness.** `gh auth status` must succeed (BLOCK on failure, not
   WARN — an expired token mid-wave strands every subagent). Probe any other
   credential the plan's tasks need (cloud CLI, API tokens) the same way.
d) **Build-wave disk floor.** The generic 2GB floor (Check 4) is for doc/code
   waves. If the wave includes parallel builds (Xcode, swift build, go build
   at scale), the floor is the global CLAUDE.md rule: BLOCK below ~20GB free
   on /System/Volumes/Data; point heavy builds at the APFS offload volume.
- Record: worktree path, branch, SHA, scheme(s), auth status, applicable
  disk floor.

---

GO/NO-GO determination

A BLOCK from any check is an unconditional NO-GO. Agents must not launch.
WARNs are advisory -- the user can choose to proceed, but should acknowledge each WARN.

Build the summary table:

```
## Preflight Report --  -- 

| Check | Status | Details |
|-------|--------|---------|
| Working directory | OK/WARN/BLOCK |  |
| Active branch | OK/WARN | main /  |
| Working tree | OK/WARN | clean / N files |
| Disk space | OK/WARN/BLOCK | GB available |
| Stale worktrees | OK/WARN | N total (CLEAN:n DIRTY:n UNMERGED:n) |
| Remote sync | OK/WARN | N ahead, M behind |
| Build sanity | OK/SKIP/BLOCK |  PASS/FAIL |
| Plan readiness | OK/WARN | N tasks, W waves |
| Projects scopes | OK/WARN/BLOCK/SKIP | accessible / missing scopes / skipped |
| Code graph | OK/WARN/SKIP | N/A or fresh / N pending files / tool missing |
| Pool readiness | OK/WARN/BLOCK/SKIP | origin+commits+plan present / N stale claims / not pool |

## Verdict: GO / NO-GO

### Blocking issues (must resolve before launching)

### Warnings (review before proceeding)

### Recommended next action

```

If --fix was passed, append a "Fixes Applied" section listing every automated fix attempted
and whether it succeeded.

---

Rules
- Never delete branches, commits, or files. The preflight is read-only by default.
- --fix only performs safe operations: stash, checkout main, pull, clean worktrees.
- --fix never force-pushes, resets, or deletes branches with unmerged work.
- If a check command fails (e.g., git command not available), report "CHECK SKIPPED: "
  and continue. Do not abort the entire preflight on a single check failure.
- Use UTC dates formatted as YYYY-MM-DD.
- ASCII only. No emojis.
- Output the full report even if the verdict is GO. The user should always see what was checked.

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [dndungu](https://github.com/dndungu)
- **Source:** [dndungu/agent-skills](https://github.com/dndungu/agent-skills)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-dndungu-agent-skills-preflight
- Seller: https://agentstack.voostack.com/s/dndungu
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
