| name | state-machine |
| description | Task lifecycle state transitions with validation gates. Defines states, triggers, and required proofs. |
| version | 0.1.0 |
| tags | ["state-machine","workflow","transitions","gates"] |
| keywords | ["state","transition","gate","validation","workflow","lifecycle"] |
| user-invocable | false |
plugin: autolinear
updated: 2026-01-20
Task Lifecycle State Machine
Version: 0.1.0
Purpose: Manage task state transitions with validation gates
Status: Phase 1
When to Use
Use this skill when you need to:
- Understand valid state transitions for tasks
- Implement validation gates before state changes
- Handle iteration loops (In Review -> In Progress)
- Manage escalation to blocked state
- Enforce iteration limits
States
Todo ──→ In Progress ──→ In Review ──→ Done
↑ │
└───────────┘
(iteration)
In Progress ──→ Blocked (escalation)
State Definitions
| State | Description | Entry Condition |
|---|
| Todo | Task queued for execution | Created with @autolinear 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 |
Transition Triggers
| From | To | Trigger | Gate |
|---|
| Todo | In Progress | Label @autolinear 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 |
Validation Gates
Gate 1: Start Work (Todo -> In Progress)
async function canStartWork(issue: Issue): Promise<boolean> {
const checks = [
extractAcceptanceCriteria(issue.description).length > 0,
(await getBlockingIssues(issue)).length === 0,
issue.assignee?.id === AUTOLINEAR_BOT_USER_ID,
];
return checks.every(c => c);
}
Gate 2: Submit for Review (In Progress -> In Review)
async function canSubmitForReview(proof: Proof): Promise<boolean> {
const checks = [
proof.testResults.passed === proof.testResults.total,
proof.buildSuccessful,
proof.lintErrors === 0,
proof.screenshots.length > 0 || proof.deploymentUrl,
];
return checks.every(c => c);
}
Gate 3: Complete (In Review -> Done)
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 };
}
return { canProceed: false, autoApproved: false };
}
Iteration Limits
| Loop Type | Max Iterations | Escalation |
|---|
| Execution retry | 2 | Block task |
| Feedback rounds | 5 | Manual intervention |
| Quality check fixes | 2 | Report to user |
Implementation
class StateMachine {
async transition(
issueId: string,
targetState: string,
proof?: Proof
): Promise<void> {
const issue = await linear.issue(issueId);
const currentState = issue.state.name;
const isValid = this.validateTransition(currentState, targetState, proof);
if (!isValid) {
throw new Error(`Invalid transition: ${currentState} -> ${targetState}`);
}
await linear.issueUpdate(issueId, {
stateId: await this.getStateId(issue.team.id, targetState),
});
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;
}
}
State Transition Diagram
┌─────────────────────────────┐
│ │
▼ │
┌──────┐ ┌─────────────┐ ┌───────────┴───┐ ┌──────┐
│ Todo │ ────► │ In Progress │ ────► │ In Review │ ────► │ Done │
└──────┘ └─────────────┘ └───────────────┘ └──────┘
│ │ │
│ │ │
│ ▼ │
│ ┌─────────┐ │
└────────► │ Blocked │ ◄─────────────────┘
└─────────┘
Examples
Example 1: Happy Path
await transitionState(issueId, 'In Progress');
await transitionState(issueId, 'In Review');
await transitionState(issueId, 'Done');
Example 2: Iteration Loop
await transitionState(issueId, 'In Progress');
await transitionState(issueId, 'In Review');
await transitionState(issueId, 'In Progress');
await transitionState(issueId, 'In Review');
await transitionState(issueId, 'Done');
Example 3: Escalation
if (iterationCount >= MAX_FEEDBACK_ROUNDS) {
await transitionState(issueId, 'Blocked');
await addComment(issueId, "Escalated: Max iterations reached");
}
Best Practices
- Always validate before transitioning
- Log all transitions for audit trail
- Include proof artifacts when transitioning to In Review
- Enforce iteration limits to prevent infinite loops
- Escalate gracefully rather than failing silently
- Comment on Linear when state changes for visibility