plugins/autopilot/skills/state-machine/SKILL.md
Task lifecycle state transitions with validation gates. Defines states, triggers, and required proofs.
npx skillsauth add madappgang/claude-code state-machineInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
plugin: autopilot updated: 2026-01-20
Version: 0.1.0 Purpose: Manage task state transitions with validation gates Status: Phase 1
Use this skill when you need to:
Todo ──→ In Progress ──→ In Review ──→ Done
↑ │
└───────────┘
(iteration)
In Progress ──→ Blocked (escalation)
| State | Description | Entry Condition | |-------|-------------|-----------------| | Todo | Task queued for execution | Created with @autopilot label | | In Progress | Task being executed | Passed start gate | | In Review | Awaiting validation | Proof generated | | Done | Task completed | Auto-approved or user approved | | Blocked | Cannot proceed | Dependency issue or escalation |
| From | To | Trigger | Gate | |------|----|---------|------| | Todo | In Progress | Label @autopilot added | Has acceptance criteria | | In Progress | In Review | Work complete | Proof >= 80% confidence | | In Review | Done | Confidence >= 95% | Auto-approval | | In Review | Done | User approves | User feedback = APPROVAL | | In Review | In Progress | Confidence < 80% | Validation failed | | In Review | In Progress | User requests changes | Feedback = REQUESTED_CHANGES | | In Progress | Blocked | Max iterations | Escalation | | * | Blocked | Unresolvable blocker | Manual trigger |
async function canStartWork(issue: Issue): Promise<boolean> {
const checks = [
// Has acceptance criteria
extractAcceptanceCriteria(issue.description).length > 0,
// No blocking dependencies
(await getBlockingIssues(issue)).length === 0,
// Assigned to autopilot
issue.assignee?.id === AUTOPILOT_BOT_USER_ID,
];
return checks.every(c => c);
}
async function canSubmitForReview(proof: Proof): Promise<boolean> {
const checks = [
// All tests pass
proof.testResults.passed === proof.testResults.total,
// Build successful
proof.buildSuccessful,
// No lint errors
proof.lintErrors === 0,
// Has proof artifacts
proof.screenshots.length > 0 || proof.deploymentUrl,
];
return checks.every(c => c);
}
async function canComplete(proof: Proof): Promise<{
canProceed: boolean;
autoApproved: boolean;
}> {
if (proof.confidence >= 95) {
return { canProceed: true, autoApproved: true };
}
if (proof.confidence >= 80) {
return { canProceed: false, autoApproved: false };
// Wait for user approval
}
return { canProceed: false, autoApproved: false };
// Validation failed, should iterate
}
| Loop Type | Max Iterations | Escalation | |-----------|----------------|------------| | Execution retry | 2 | Block task | | Feedback rounds | 5 | Manual intervention | | Quality check fixes | 2 | Report to user |
class StateMachine {
async transition(
issueId: string,
targetState: string,
proof?: Proof
): Promise<void> {
const issue = await linear.issue(issueId);
const currentState = issue.state.name;
// Validate transition
const isValid = this.validateTransition(currentState, targetState, proof);
if (!isValid) {
throw new Error(`Invalid transition: ${currentState} -> ${targetState}`);
}
// Execute transition
await linear.issueUpdate(issueId, {
stateId: await this.getStateId(issue.team.id, targetState),
});
// Log transition
await this.logTransition(issueId, currentState, targetState, proof);
}
private validateTransition(
from: string,
to: string,
proof?: Proof
): boolean {
const validTransitions: Record<string, string[]> = {
'Todo': ['In Progress', 'Blocked'],
'In Progress': ['In Review', 'Blocked'],
'In Review': ['Done', 'In Progress'],
'Blocked': ['Todo', 'In Progress'],
};
return validTransitions[from]?.includes(to) ?? false;
}
}
┌─────────────────────────────┐
│ │
▼ │
┌──────┐ ┌─────────────┐ ┌───────────┴───┐ ┌──────┐
│ Todo │ ────► │ In Progress │ ────► │ In Review │ ────► │ Done │
└──────┘ └─────────────┘ └───────────────┘ └──────┘
│ │ │
│ │ │
│ ▼ │
│ ┌─────────┐ │
└────────► │ Blocked │ ◄─────────────────┘
└─────────┘
// Task created
await transitionState(issueId, 'In Progress'); // Gate: Has acceptance criteria
// Work complete, proof generated
await transitionState(issueId, 'In Review'); // Gate: Proof >= 80%
// High confidence auto-approval
await transitionState(issueId, 'Done'); // Gate: Confidence >= 95%
// First attempt
await transitionState(issueId, 'In Progress');
await transitionState(issueId, 'In Review'); // Confidence: 85%
// User requests changes
await transitionState(issueId, 'In Progress'); // Feedback: REQUESTED_CHANGES
// Second attempt
await transitionState(issueId, 'In Review'); // Confidence: 97%
await transitionState(issueId, 'Done'); // Auto-approved
// After 5 feedback rounds
if (iterationCount >= MAX_FEEDBACK_ROUNDS) {
await transitionState(issueId, 'Blocked');
await addComment(issueId, "Escalated: Max iterations reached");
}
testing
A test skill for validation testing. Use when testing skill parsing and validation logic.
tools
--- name: bad-skill description: This skill has invalid YAML in frontmatter allowed-tools: [invalid, array, syntax prerequisites: not-an-array --- # Bad Skill This skill has malformed frontmatter that should fail parsing. The YAML has: - Unclosed array bracket - Wrong type for prerequisites (should be array, not string)
tools
Plugin release process for MAG Claude Plugins marketplace. Covers version bumping, marketplace.json updates, git tagging, and common mistakes. Use when releasing new plugin versions or troubleshooting update issues.
testing
Fetch trending programming models from OpenRouter rankings. Use when selecting models for multi-model review, updating model recommendations, or researching current AI coding trends. Provides model IDs, context windows, pricing, and usage statistics from the most recent week.