# Plan Validator

> On-demand plan-tree validator. Runs all 8 invariants from spec §6.7 (parent existence, children integrity, no orphans, valid status, monotonic revision, test_ref existence, DAG no-cycles, freeze_reason). Refuses commits on violations.

- Skill: `nguyenthienthanh/plan-validator` (Agent Skill)
- Install (CLI): `npx skillmds@latest add nguyenthienthanh/plan-validator`
- Raw SKILL.md: https://api.skillmd.com/api/skills/nguyenthienthanh/plan-validator/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: nguyenthienthanh (https://skillmd.com/u/nguyenthienthanh)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/nguyenthienthanh/plan-validator

---


> **AI-consumed reference.** Optimized for Claude to read during execution.
> Human-readable explanation: see [docs/architecture/HIERARCHICAL_PLANNING.md](../../../docs/architecture/HIERARCHICAL_PLANNING.md)
> or [docs/getting-started/](../../../docs/getting-started/) depending on topic.


# Plan Validator

**STATUS — v3.7.0-alpha.2.** Thin wrapper over `aura-frog/scripts/plans/validate-plan-tree.sh`.

## Behavior

1. Detect: if `.claude/plans/` does NOT exist → exit silently
2. Run `bash aura-frog/scripts/plans/validate-plan-tree.sh`
3. If exit_code === 0 → silent (or one-line success when `verbose: true`)
4. If exit_code !== 0 → surface the failing invariant(s) and refuse the calling operation

## The 8 invariants (spec §6.7)

| # | Invariant | Failure mode |
|---|-----------|--------------|
| 1 | parent existence | Every node's `parent` field points to an existing node (or `MISSION` for T1) |
| 2 | children integrity | Every `children: [...]` entry exists as a node file |
| 3 | no orphans | Every non-MISSION node is referenced by exactly one parent |
| 4 | valid status | `status` ∈ {planned, active, done, blocked, frozen, discarded, archived} |
| 5 | monotonic revision | `revision` only increases; never decreases or skips |
| 6 | test_ref existence | When `test_ref:` set, the referenced test file exists |
| 7 | DAG no-cycles | `depends_on:` does not introduce cycles when traversed |
| 8 | freeze_reason | `status: frozen` requires `freeze_reason:` and `frozen_at:` fields |

## When to invoke

- **Before** `/aura-frog:plan-expand`, `/aura-frog:plan-promote`, `/aura-frog:plan-archive`
- **Before** `git commit` when `.claude/plans/` has uncommitted changes
- **After** any direct file edit on `.claude/plans/*.md` (manual override)

## When NOT to invoke

- Read-only commands (`/aura-frog:plan-status`, `/aura-frog:trace`) — running validation on a healthy tree is wasted overhead
- During `/aura-frog:plan-undo` — the post-restore state may transiently violate invariants while restoring
- Inside hooks fired on every PreToolUse — too expensive

## Output discipline

- Exit 0: silent (or `✓ Plan tree valid (8/8 invariants pass)` if verbose)
- Exit 1: enumerate every failing invariant, one per line, with the offending node ID

## Tie-Ins

- **Spec:** §6.7, §9.2
- **Script:** `aura-frog/scripts/plans/validate-plan-tree.sh` — actual implementation
- **Skill:** `plan-loader` — companion (loader is read-only; this is the validator)
- **Agent:** `master-planner` — invokes before mutations
- **Command:** `/aura-frog:plan-expand`, `/aura-frog:plan-promote`, `/aura-frog:plan-archive` — invoke before applying
- **Rule:** `rules/workflow/plan-lifecycle.md` — invariant 4 enforces valid status transitions

