From dev-workflow
Use after all phases of a dev-guide are complete, or when the user says 'finalize', 'final check', 'cross-phase validation'. Runs full test suite, verifies acceptance criteria across all phases, audits cumulative test coverage, and produces a final validation report.
npx claudepluginhub n0rvyn/indie-toolkit --plugin dev-workflowThis skill is limited to using the following tools:
Cross-phase validation gate. Runs after all dev-guide phases are complete to catch regressions, missing tests, and broken acceptance criteria that per-phase reviews miss.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Designs and optimizes AI agent action spaces, tool definitions, observation formats, error recovery, and context for higher task completion rates.
Cross-phase validation gate. Runs after all dev-guide phases are complete to catch regressions, missing tests, and broken acceptance criteria that per-phase reviews miss.
Validate preconditions (all phases done?)
→ Full test suite (0 fail, 0 skip)
→ Cross-phase acceptance criteria regression check
→ Dev-guide scope deliverable verification
→ Cumulative test coverage audit
→ Generate report
→ Present results
.claude/dev-workflow-state.yml using the Read tool.
dev_guide path from itdocs/06-plans/*-dev-guide.md. If docs/06-plans/ does not exist, ask user for the dev-guide path via AskUserQuestion. If multiple dev-guides found, prefer the file with current: true in frontmatter; if none has current:, ask user.## Phase N: sections. For each Phase:
- [x] = checked, - [ ] = uncheckedtotal_phases, phase_list, dev_guide_path, override (true/false)package.json exists → npm testCargo.toml exists → cargo testpyproject.toml or setup.py exists → pytestgo.mod exists → go test ./...*.xcodeproj or *.xcworkspace exists → detect scheme via xcodebuild -list -json, pick the scheme containing "Tests" or the main app scheme; use -destination 'platform=iOS Simulator,name=iPhone 16' (fallback: platform=macOS); if detection fails, fall through to "ask user"/finalize./finalize.ConfigManager, paths with / or .swift/.ts extensions) and determine verification type:| Criterion pattern | Check method | Example |
|---|---|---|
Contains file/directory path (has / or file extension) | test -f {path} or ls {path} | "Config file at Sources/Config.swift" → check file |
| Contains a proper-cased identifier (PascalCase or camelCase) | Grep for that identifier | "ConfigManager handles settings" → grep ConfigManager |
| Contains "test" + file reference | Verify test file exists and is non-empty | "Unit tests for DataStore" → check test file |
| Contains "compiles" / "builds" / "no errors" | Already covered by Step 2 | skip |
| No extractable identifier or path | Mark as "manual verification needed" | "Users can log in with OAuth" → manual |
Do NOT pattern-match generic English words like "class", "function", "set". Only extract identifiers that are code symbols (PascalCase, camelCase, snake_case, or quoted names).
Cross-Phase Acceptance Criteria:
| Phase | Criterion | Check | Result |
|-------|-----------|-------|--------|
| 1 | Config file at Sources/Config.swift | file exists | ✅ |
| 2 | SettingsView renders options | grep SettingsView | ✅ |
| 3 | Push notifications registered | grep UNUserNotification | ❌ REGRESSION |
This step catches scope items promised in the dev-guide but never created — the gap that per-phase reviews miss when phases are executed without the full plan/verify/review cycle.
ChannelForm.tsx, ConfigManager.swift, auth.test.tspath/to/file patterns: web/src/components/channels/ChannelCard.tsx{Token}.{inferred extension} based on project language| Check | Method |
|---|---|
| Exact path given | test -f {path} |
| Filename only (no directory) | find . -name "{filename}" -not -path "*/node_modules/*" -not -path "*/.git/*" |
| Component name (no extension) | Grep for {name} in source files matching the project's primary extensions |
Dev-Guide Scope Deliverables:
| Phase | Deliverable | Check | Result |
|-------|-------------|-------|--------|
| 12 | ChannelForm.tsx | find -name | ❌ NOT FOUND |
| 12 | ChannelCard.tsx | find -name | ❌ NOT FOUND |
| 12 | ChannelMessages.tsx | find -name | ✅ Found at web/src/pages/Channels.tsx:L45 |
This step catches tests that per-phase implementation-reviewer missed.
Collect all plan files:
Plan: field)docs/06-plans/*-plan.md and match by phase name/number in the plan's ## Context or Scope: headerExtract test requirements from plans:
**Files:** sections, or tasks that are explicitly test tasks (title contains "test", "Test", category "testing")Verify each required test file:
| Check | Method | Status |
|---|---|---|
| File exists | test -f {path} | T-exist |
| Non-empty (has test functions) | File length > minimal threshold + contains test function signatures | T-content |
| Has assertions | Grep for assertion patterns: #expect, XCTAssert, expect(, assert, it(", test(", .to(, .toBe( | T-assert |
Classify each test file:
Scan for untested source files:
git log --diff-filter=A --format=%H -- {dev_guide_path} | head -1 via Bash and store the hashgit diff --name-only {base_commit} -- '*.swift' '*.ts' '*.tsx' '*.js' '*.jsx' '*.py' '*.go' '*.rs' via Bash (omit HEAD to include uncommitted changes)FooTests.swift for Foo.swift, foo.test.ts for foo.ts, test_foo.py for foo.py)Output:
Cumulative Test Coverage:
Plan-required tests: {N}
- ✅ Covered (exist + assertions): {M}
- ⚠️ Shell (exist, no assertions): {K}
- ❌ Missing: {J}
| Plan | Test File | Status |
|------|-----------|--------|
| Phase 1 plan | Tests/ConfigTests.swift | ✅ |
| Phase 2 plan | Tests/SettingsViewTests.swift | ⚠️ Shell |
| Phase 3 plan | Tests/NotificationTests.swift | ❌ Missing |
Untested source files (no corresponding test):
- Sources/Helpers/DateFormatter.swift
- Sources/Services/CacheManager.swift
.claude/dev-workflow-state.yml exists, update it:
phase_step: finalized
last_updated: "<now>"
This prevents the SessionStart hook from prompting "Resume phase?" after finalization.mkdir -p .claude/reviews.claude/reviews/finalize-{YYYY-MM-DD-HHmmss}.md:# Finalization Report
**Dev-guide:** {path}
**Date:** {YYYY-MM-DD HH:MM}
**Phases:** {N} total, {M} validated
{If override: **⚠️ Override:** Phases {list} had unchecked criteria}
## Test Suite
- Runner: {detected runner}
- Total: {N}, Passed: {P}, Failed: {F}, Skipped: {S}
- Result: ✅ All tests pass / ❌ {F} failures, {S} skipped
## Cross-Phase Acceptance Criteria
- Total criteria: {N}
- Auto-verified: {M} ✅
- Regressions: {K} ❌
- Manual verification needed: {J} ⚠️
{criteria table from Step 3}
## Scope Deliverables
- Total deliverables extracted: {N}
- Found: {M} ✅
- Not found: {K} ❌
{deliverables table from Step 3.5}
## Cumulative Test Coverage
- Plan-required tests: {N}
- Covered: {M} ✅
- Shell/empty: {K} ⚠️
- Missing: {J} ❌
{coverage table from Step 4}
## Untested Source Files
{list from Step 4, or "None"}
## Verdict
{One of:}
✅ Ready for integration — all tests pass, no regressions, full coverage
⚠️ Conditionally ready — all tests pass, {N} warnings (see above)
❌ Not ready — {summary of blocking issues}
### Action Items
{Numbered list of issues to fix, if any}
### Manual Verification Checklist
{Items marked "manual" from Step 3, if any}
- [ ] {criterion — in spatial/behavioral language}
Finalization complete.
Tests: {P}/{N} pass, {S} skip, {F} fail
Criteria: {M}/{N} verified, {K} regressions, {J} manual
Scope: {M}/{N} deliverables found, {K} missing
Coverage: {M}/{N} plan-required covered, {K} shell, {J} missing
Untested files: {count}
Report: .claude/reviews/finalize-{timestamp}.md
Verdict: ✅ Ready / ⚠️ Warnings / ❌ Not ready
/commit to save, then /finish-branch to integrate. Consider /generate-bases-views to update knowledge views."/commit and /finish-branch. Otherwise fix and re-run /finalize."/finalize."/finalize invocation produces a new timestamped report. Previous reports are not overwritten..claude/reviews/