| name | faber-state |
| description | Manage FABER workflow state (CRUD operations) |
| model | claude-opus-4-5 |
FABER State Skill
State is stored at:
- With run_id:
.fractary/plugins/faber/runs/{run_id}/state.json - Legacy (no run_id):
.fractary/plugins/faber/state.json
State tracks: current phase, phase statuses, artifacts, retry counts, errors, last_event_id
YOU MUST NOT:
- Make decisions about workflow progression (that's the agent's job)
- Skip state validation
- Delete state without explicit request
Note: Steps in state use id field for identification. For backward compatibility with existing state files, name field is also supported during reads.
init-state
Initialize a new workflow state file.
Script: ../core/scripts/state-init.sh
Parameters:
work_id(required): Work item identifierrun_id(optional): Run identifier (format: org/project/uuid). If provided, state is stored in per-run directory.workflow_id(optional): Workflow to use (default: "default")state_path(optional): Path to state file (computed from run_id if provided)
Returns:
{
"status": "success",
"operation": "init-state",
"work_id": "123",
"run_id": "fractary/my-project/a1b2c3d4-...",
"workflow_id": "default",
"state_path": ".fractary/plugins/faber/runs/fractary/my-project/a1b2c3d4-.../state.json"
}
Execution:
# With run_id (preferred for new workflows)
../core/scripts/state-init.sh --run-id "$RUN_ID" "$WORK_ID" "$WORKFLOW_ID"
# Legacy (without run_id)
../core/scripts/state-init.sh "$WORK_ID" "$WORKFLOW_ID" "$STATE_PATH"
read-state
Read current workflow state.
Script: ../core/scripts/state-read.sh
Parameters:
run_id(optional): Run identifier. If provided, reads from per-run directory.state_path(optional): Path to state file (computed from run_id if provided)query(optional): jq query for specific field (e.g.,.current_phase)
Returns:
{
"status": "success",
"operation": "read-state",
"state": { ... full state object ... }
}
Or with query:
{
"status": "success",
"operation": "read-state",
"query": ".current_phase",
"result": "build"
}
Execution:
# With run_id (preferred)
../core/scripts/state-read.sh --run-id "$RUN_ID" "$QUERY"
# Legacy
../core/scripts/state-read.sh "$STATE_PATH" "$QUERY"
update-phase
Update a phase's status and data.
Script: ../core/scripts/state-update-phase.sh
Parameters:
run_id(optional): Run identifier. If provided, updates per-run state.phase(required): Phase name (frame, architect, build, evaluate, release)status(required): New status (pending, in_progress, completed, failed, skipped)data(optional): Additional phase data as JSON
Returns:
{
"status": "success",
"operation": "update-phase",
"phase": "build",
"phase_status": "in_progress",
"current_phase": "build"
}
Execution:
# With run_id (preferred)
../core/scripts/state-update-phase.sh --run-id "$RUN_ID" "$PHASE" "$STATUS" "$DATA_JSON"
# Legacy
../core/scripts/state-update-phase.sh "$PHASE" "$STATUS" "$DATA_JSON"
update-step
Update a step's status within a phase.
Parameters:
run_id(optional): Run identifier. If provided, updates per-run state.phase(required): Phase containing the stepstep_id(required): Unique identifier of the step (usesidfield, falls back tonamefor backward compatibility)status(required): New status (pending, in_progress, completed, failed, skipped)data(optional): Step result data
Returns:
{
"status": "success",
"operation": "update-step",
"phase": "build",
"step_id": "implement",
"step_status": "completed"
}
Execution:
- Compute state path from run_id if provided
- Read current state
- Find step in phase.steps array by matching
step_id(checkidfield first, thennamefor backward compatibility) - Update step status and data
- Write state back
Note: Step identification uses the id field (preferred) or name field (deprecated, backward compatible). This ensures consistent step tracking across logging, state management, and step targeting.
record-artifact
Record an artifact in state (spec, branch, PR, etc.).
Parameters:
run_id(optional): Run identifier. If provided, updates per-run state.artifact_type(required): Type of artifact (spec_path, branch_name, pr_url, pr_number, custom)artifact_value(required): Value to record
Returns:
{
"status": "success",
"operation": "record-artifact",
"artifact_type": "branch_name",
"artifact_value": "feat/123-add-feature"
}
Execution:
- Compute state path from run_id if provided
- Read current state
- Set
state.artifacts[artifact_type] = artifact_value - Update
updated_attimestamp - Write state back
mark-complete
Mark the workflow as completed or failed.
Parameters:
run_id(optional): Run identifier. If provided, updates per-run state.final_status(required): Final status (completed, failed, cancelled)summary(optional): Completion summaryerrors(optional): Error details if failed
Returns:
{
"status": "success",
"operation": "mark-complete",
"final_status": "completed",
"completed_at": "2025-12-03T11:00:00Z"
}
Execution:
- Compute state path from run_id if provided
- Read current state
- Set
state.status = final_status - Set
state.completed_at = now() - Add summary/errors if provided
- Write state back
update-step-progress
Track exact step progress within a phase (for resume support).
Parameters:
run_id(optional): Run identifier. If provided, updates per-run state.phase(required): Current phase being executedcurrent_step_index(required): Index of the current/next step in the phasesteps_completed(required): Array of step names/IDs that have been completed
Returns:
{
"status": "success",
"operation": "update-step-progress",
"phase": "build",
"current_step_index": 2,
"steps_completed": ["generate-spec", "create-branch"],
"resumable": true
}
Execution:
- Compute state path from run_id if provided
- Read current state
- Set
state.current_phase = phase - Set
state.current_step_index = current_step_index - Set
state.steps_completed = steps_completed - Update
updated_attimestamp - Write state back
Purpose: This operation enables exact-step resume by tracking:
- Which phase we're currently in
- Which step index we're at (0-indexed)
- Which steps have already been completed
When resuming with --resume, the executor reads this state and passes it
to faber-manager as resume_context, allowing the manager to skip completed
steps and continue from the exact position.
increment-retry
Increment the retry counter for the current phase (for Build-Evaluate loop).
Parameters:
run_id(optional): Run identifier. If provided, updates per-run state.phase(optional): Phase to increment retry for (default: current_phase)
Returns:
{
"status": "success",
"operation": "increment-retry",
"phase": "evaluate",
"retry_count": 2,
"max_retries": 3,
"can_retry": true
}
Execution:
- Compute state path from run_id if provided
- Read current state
- Increment
state.phases[phase].retry_count - Check against max_retries from workflow config
- Write state back
check-exists
Check if a state file exists for a run or work item.
Parameters:
run_id(optional): Run identifier. If provided, checks per-run state.work_id(optional): Work ID to check (legacy)state_path(optional): Specific state file path (computed from run_id if provided)
Returns:
{
"status": "success",
"operation": "check-exists",
"exists": true,
"run_id": "fractary/my-project/a1b2c3d4-...",
"state_path": ".fractary/plugins/faber/runs/fractary/my-project/a1b2c3d4-.../state.json",
"work_id": "123",
"current_phase": "build"
}
validate-state
Validate state file structure.
Script: ../core/scripts/state-validate.sh
Parameters:
run_id(optional): Run identifier. If provided, validates per-run state.state_path(optional): Path to state file (computed from run_id if provided)
Returns:
{
"status": "success",
"operation": "validate-state",
"valid": true,
"run_id": "fractary/my-project/a1b2c3d4-..."
}
backup-state
Create a backup of current state.
Script: ../core/scripts/state-backup.sh
Parameters:
run_id(optional): Run identifier. If provided, backs up per-run state.state_path(optional): Path to state file (computed from run_id if provided)
Returns:
{
"status": "success",
"operation": "backup-state",
"backup_path": ".fractary/plugins/faber/runs/fractary/my-project/a1b2c3d4-.../state.json.backup.20251203T110000Z"
}
Parse Request
- Extract operation name
- Extract parameters
- Set default state path if not provided
Execute Operation
- Use appropriate script or inline logic
- For writes: read → modify → write atomically
Return Result
- Always return structured JSON
- Include status field (success/error)
- Include operation-specific data
🎯 STARTING: FABER State
Operation: update-phase
Phase: build
Status: in_progress
───────────────────────────────────────
[... execution ...]
✅ COMPLETED: FABER State
Phase: build → in_progress
Current Phase: build
───────────────────────────────────────
Legacy (no run_id):
- State file:
.fractary/plugins/faber/state.json - Backup pattern:
.fractary/plugins/faber/state.json.backup.<timestamp>
Helper function to compute state path:
get_state_path() {
local run_id="$1"
if [ -n "$run_id" ]; then
echo ".fractary/plugins/faber/runs/$run_id/state.json"
else
echo ".fractary/plugins/faber/state.json"
fi
}