From cappy-toolkit
Inter-phase transition orchestration for CAPPY — evaluates phase gates, extracts context from phase JSON results, checks inv_context.json health, and prepares HITL checkpoint content for Main Claude.
npx claudepluginhub thelightarchitect/cappy-toolkit --plugin cappy-toolkitThis skill uses the workspace's default tool permissions.
<!-- Copyright (C) 2025-2026 Kevin Francis Tan (github.com/theLightArchitect) | SPDX-License-Identifier: AGPL-3.0-or-later -->
Generates design tokens/docs from CSS/Tailwind/styled-components codebases, audits visual consistency across 10 dimensions, detects AI slop in UI.
Records polished WebM UI demo videos of web apps using Playwright with cursor overlay, natural pacing, and three-phase scripting. Activates for demo, walkthrough, screen recording, or tutorial requests.
Delivers idiomatic Kotlin patterns for null safety, immutability, sealed classes, coroutines, Flows, extensions, DSL builders, and Gradle DSL. Use when writing, reviewing, refactoring, or designing Kotlin code.
Version: 1.0.0 Purpose: Inter-phase gate evaluation, context extraction, inv_context.json health check, and HITL checkpoint preparation Invoked By: Main Claude via SP-HANDOFF after receiving a phase JSON result MCP Tools: None — reads inv_context.json and phase result JSON directly Reasoning Libraries: gate.md (thresholds), escalation.md (2nd failure path), logging.md (audit trail)
At the very start of execution, output this exact block:
[ Phase → — Handoff ]
Tools: loop-decision (Phase 4 only), inv_context.json
Then before each tool call, output a one-liner:
→ {tool-name} {key parameter}
CAPPY owns: Gate evaluation, score extraction, variable population, health checks, audit trail writes, failure tracking, HITL summary construction.
Main Claude owns: Presenting the HITL checkpoint to Kevin and waiting for his decision before triggering the next spawn.
This sub-skill produces a HandoffResult JSON. Main Claude reads it, formats the HITL checkpoint message, and asks Kevin whether to proceed.
Receive {phase_result} (JSON from the completed phase sub-skill). Extract:
gate_status = phase_result.gate_status ("PASS" | "FAIL")
completed_phase = phase_result.phase
score_field = the primary quality score for this phase (see table below)
score_value = phase_result.{score_field}
threshold = phase_result.threshold
recommendation = phase_result.recommendation
recovery_options = phase_result.recovery_options (list, may be empty)
Score field by phase:
| Completed Phase | Score Field | Threshold |
|---|---|---|
| 2 (Triage) | confidence_score | 70% |
| 3 (Evidence) | completeness_score | 80% |
| 4 (Hypothesis) | coherence_score | 85% |
| 5 (Validation) | quality_score | 85% |
| 6 (Solution) | narrative_coherence_score | 80% |
| 7 (Deliverables) | verification_rate × 100 | 90% |
Read {case_dir}/inv_context.json. Verify:
case, claims, phases, audit_trail).phases.phase_{completed_phase} has status, started_at.claims[] where verification.status == "UNVERIFIED".FAIL entries in audit_trail[] for this phase.If inv_context.json is missing or malformed — return health_check_failed=true. Do not proceed.
gate_pass = (gate_status == "PASS")
prior_failures = count of audit_trail entries where phase={completed_phase} AND outcome="GATE_FAIL"
Escalation rule: If gate_pass == false AND prior_failures >= 1 (this is the 2nd failure for this phase) → set escalate = true. CAPPY cannot retry indefinitely.
Based on the transition, extract the variables needed to populate the next spawn prompt:
Phase 2 → Phase 3 (SP-2):
phase_2_confidence = phase_result.confidence_score
top_patterns_summary = phase_result.patterns_found (first 3 entries, format as "P-ID: description" list)
file_list = inv_context.json → evidence.files[] with status != "EXCLUDED"
depth = "standard" | "deep" (set "deep" if confidence_score < 75%)
Phase 3 → Phase 4 (SP-3):
phase_2_confidence = inv_context.json → phases.phase_2.confidence_score
top_patterns_summary = inv_context.json → phases.phase_2.top_patterns_summary
phase_3_completeness = phase_result.completeness_score
key_errors_summary = phase_result.errors_found (top 5, one-line each)
correlations_summary = phase_result.pattern_correlations (top 3)
evidence_gaps = phase_result.evidence_gaps (list)
Phase 4 → Phase 5 (SP-4):
phase_2_confidence = inv_context.json → phases.phase_2.confidence_score
top_patterns_summary = inv_context.json → phases.phase_2.top_patterns_summary
hypothesis = phase_result.hypothesis
confidence_tier = phase_result.confidence_tier
coherence_score = phase_result.coherence_score
weak_assumptions = phase_result.weak_assumptions (full list)
phase_5_targets = phase_result.phase_5_targets (full list)
Phase 5 → Phase 6 (SP-SOLUTION):
hypothesis = inv_context.json → hypotheses.list[0].statement (primary surviving)
confidence_tier = inv_context.json → hypotheses.list[0].confidence_tier
quality_score = phase_result.quality_score
validation_sources_count = count of phase_result.validation_sources
validated_hypothesis = phase_result.validated_hypothesis | hypothesis
jira_match_ticket = phase_result.jira_matches[0].ticket | "none"
Phase 6 → Phase 7 (SP-5):
hypothesis = inv_context.json → hypotheses.list[0].statement (primary surviving)
quality_score = inv_context.json → phases.phase_5.quality_score
validation_sources = inv_context.json → phases.phase_5.validation_sources_count
jira_match_ticket = inv_context.json → phases.phase_5.jira_match_ticket | "none"
deliverable_types = ["customer_response", "jira_draft"] (default; override if Kevin specified)
Append to inv_context.json → audit_trail[]:
{
"timestamp": "{ISO-8601 now}",
"actor": "CAPPY",
"action": "PHASE_HANDOFF",
"phase": {completed_phase},
"gate_status": "{PASS | FAIL}",
"score": {score_value},
"threshold": {threshold},
"unverified_claims": {unverified_count},
"escalate": {true | false},
"next_phase": {next_phase | null}
}
Also mark inv_context.json → phases.phase_{completed_phase}.status = "COMPLETE" and set completed_at.
Construct the message Main Claude will present to Kevin. Include:
Phase {N} — {PASS | FAIL}
Score: {score_value}% (threshold: {threshold}%)
Unverified claims: {count}
{If PASS}:
Summary: {recommendation}
Ready for Phase {next_phase}. Proceed?
{If FAIL, first failure}:
What failed: {recommendation}
Recovery options:
1. {recovery_options[0]}
2. {recovery_options[1]}
...
Retry Phase {N} or choose recovery?
{If FAIL, 2nd failure → escalate}:
Phase {N} has failed twice. Escalating via SP-6.
Trigger: {recommendation}
{
"phase": {completed_phase},
"gate_status": "PASS | FAIL",
"score": 0.0,
"threshold": 0,
"unverified_claims": 0,
"prior_failures": 0,
"escalate": false,
"health_check_failed": false,
"next_phase": null,
"next_spawn": "SP-2 | SP-3 | SP-4 | SP-5 | SP-6 | SP-7 | null",
"next_spawn_vars": {
"phase_2_confidence": null,
"top_patterns_summary": null
},
"hitl_summary": "Phase N — PASS\nScore: X%...",
"recovery_options": [],
"audit_entry_written": true
}
next_phase mapping:
| Completed | Next (on PASS) | Next Spawn |
|---|---|---|
| 2 | 3 | SP-2 |
| 3 | 4 | SP-3 |
| 4 | 5 | SP-4 |
| 5 | 6 | SP-SOLUTION |
| 6 | 7 | SP-5 |
| 7 | null (done) | — |
Return this JSON to Main Claude.