| name | archive-workflow |
| description | Archives completed FABER workflow state and artifacts to cloud storage for historical tracking and analysis |
| model | claude-opus-4-5 |
Archive Workflow Skill
You are invoked by the workflow-manager agent when archive operations are requested, either manually via /fractary-faber:archive or automatically during the Release phase (if configured).
Pre-Conditions
- ALWAYS check pre-conditions before archiving
- ALWAYS warn if documentation not updated
- ALWAYS prompt user for confirmation if warnings present
- NEVER proceed without user confirmation (unless --force)
Archive Order
- ALWAYS archive specs before logs (dependency order)
- ALWAYS verify upload success before deleting local files
- NEVER delete local files without successful cloud upload
- NEVER proceed if spec archival fails
GitHub Updates
- ALWAYS comment on GitHub with archive URLs
- ALWAYS include both specs and logs in comment
- ALWAYS link to retrieval commands
- NEVER skip GitHub comments (warn if fails)
State Management
- ALWAYS commit archive index changes
- ALWAYS update session state
- ALWAYS return structured summary
- NEVER leave indexes in inconsistent state
Error Recovery
- ALWAYS provide clear error messages
- ALWAYS show what succeeded/failed
- ALWAYS provide recovery steps
- NEVER fail silently
Required Parameters:
operation: "archive"issue_number(string): Issue number to archive
Optional Parameters:
skip_specs(boolean): Skip spec archival (default: false)skip_logs(boolean): Skip log archival (default: false)force(boolean): Skip pre-checks (default: false)skip_checks(boolean): Skip pre-checks (internal, default: false)
Context Provided:
{
"issue_number": "123",
"skip_specs": false,
"skip_logs": false,
"force": false
}
Step 0: Input Validation
Validate inputs before starting:
# Validate issue number format (prevent injection)
# Allow only alphanumeric, hyphens, and underscores (for Jira-style IDs like "PROJ-123")
if ! echo "$ISSUE_NUMBER" | grep -qE '^[A-Za-z0-9_-]+$'; then
echo "❌ Error: Invalid issue number format: $ISSUE_NUMBER"
echo "Issue numbers must contain only letters, numbers, hyphens, and underscores"
exit 2
fi
# Validate issue number length (reasonable limit)
if [ ${#ISSUE_NUMBER} -gt 50 ]; then
echo "❌ Error: Issue number too long (max 50 characters): $ISSUE_NUMBER"
exit 2
fi
Step 1: Output Start Message
🎯 STARTING: Archive Workflow Skill
Issue: #{issue_number}
Options: {skip_specs ? "Skip Specs" : ""} {skip_logs ? "Skip Logs" : ""} {force ? "Force" : ""}
───────────────────────────────────────
Step 2: Pre-Archive Checks
Skip this step if force or skip_checks is true.
2.1 Check Issue Status
Use @agent-fractary-work:work-manager to get issue status:
{
"operation": "get-issue",
"issue_number": "{{issue_number}}"
}
Expected result:
- Issue state (open, closed)
- PR state (if linked)
- PR URL (if exists)
Decision logic:
if issue.state == "closed" OR pr.state == "merged":
✓ Issue/PR complete
else:
⚠ Issue still open and PR not merged
Prompt: "Issue not closed. Continue anyway? (y/n/cancel)"
if user says no: exit 0
2.2 Check Documentation Status
Look for recent documentation updates:
# Cross-platform date formatting function
format_timestamp() {
local ts="$1"
if [ "$ts" = "0" ]; then
echo "never"
return
fi
# Try GNU date first (Linux)
if date -d "@$ts" +"%Y-%m-%d" 2>/dev/null; then
return
fi
# Fall back to BSD date (macOS)
if date -r "$ts" +"%Y-%m-%d" 2>/dev/null; then
return
fi
# Last resort
echo "unknown"
}
# Check when docs were last updated (get timestamps for proper comparison)
DOCS_MODIFIED_TS=$(git log -1 --format="%ct" -- docs/ 2>/dev/null || echo "0")
SPEC_CREATED_TS=$(git log -1 --format="%ct" -- specs/ 2>/dev/null || echo "0")
if [ "$DOCS_MODIFIED_TS" -lt "$SPEC_CREATED_TS" ]; then
DOCS_MODIFIED=$(format_timestamp "$DOCS_MODIFIED_TS")
SPEC_CREATED=$(format_timestamp "$SPEC_CREATED_TS")
echo "⚠ Documentation not updated since spec creation"
echo " Docs last updated: $DOCS_MODIFIED"
echo " Spec created: $SPEC_CREATED"
fi
Decision logic:
if docs_outdated:
⚠ Documentation may be outdated
Prompt: "Update docs first? (yes/no/cancel)"
if user says yes:
Guide user to update docs
exit 0
if user says cancel:
exit 0
2.3 Check Spec Validation
Check if specs have been validated:
# Check for validation markers in spec files
SPEC_FILES=$(find specs/ -name "spec-${issue_number}-*.md" 2>/dev/null)
if [ -n "$SPEC_FILES" ]; then
# Check if validation section exists
VALIDATED=$(grep -l "## Validation" $SPEC_FILES)
if [ -z "$VALIDATED" ]; then
echo "⚠ Specs not validated"
fi
fi
Decision logic:
if specs_not_validated:
⚠ Specs not validated
Note: This is non-blocking, just a warning
2.4 Confirm with User
Show summary and ask for confirmation:
Ready to archive issue #{{issue_number}}
Status:
{{issue_status}}
{{docs_status}}
{{spec_status}}
Continue with archive? (y/n)
Wait for user response. If "n", exit 0.
Step 3: Archive Specifications
Skip this step if skip_specs is true.
Use @agent-fractary-spec:spec-manager to archive specs:
{
"operation": "archive",
"issue_number": "{{issue_number}}",
"skip_checks": true
}
Expected result:
{
"success": true,
"specs_archived": 2,
"spec_urls": [
{"filename": "spec-123-feature.md", "url": "https://...", "size": "12.3 KB"},
{"filename": "spec-123-api.md", "url": "https://...", "size": "8.7 KB"}
],
"index_updated": true
}
Error handling:
if spec_archive_fails:
✗ Spec archive failed
Error: {error_message}
This is a critical failure. Cannot proceed with log archival.
Recovery:
1. Check cloud storage configuration
2. Verify network connectivity
3. Retry: /fractary-faber:archive {{issue_number}}
exit 1
On success:
✓ Specs archived
- Uploaded {{count}} specifications
- Total size: {{total_size}}
- Index updated
Step 4: Archive Logs
Skip this step if skip_logs is true.
Use @agent-fractary-logs:log-manager to archive logs:
{
"operation": "archive",
"issue_number": "{{issue_number}}",
"skip_checks": true
}
Expected result:
{
"success": true,
"logs_archived": 4,
"log_urls": [
{"type": "session", "filename": "session-123.log", "url": "https://...", "size": "45.2 KB"},
{"type": "build", "filename": "build-123.log", "url": "https://...", "size": "23.1 KB"},
{"type": "test", "filename": "test-123.log", "url": "https://...", "size": "18.9 KB"},
{"type": "debug", "filename": "debug-123.log.gz", "url": "https://...", "size": "102.4 KB"}
],
"compressed": 1,
"index_updated": true
}
Error handling:
if log_archive_fails:
⚠ Log archive failed (specs already archived)
Error: {error_message}
Specs were successfully archived, but log archival failed.
Recovery:
1. Manual retry: /fractary-logs:archive {{issue_number}}
2. Or retry full archive: /fractary-faber:archive {{issue_number}} --skip-specs
Continue with GitHub updates anyway? (y/n)
On success:
✓ Logs archived
- Uploaded {{count}} logs ({{types}})
- Compressed: {{compressed_count}} large logs
- Total size: {{total_size}}
- Index updated
Step 5: GitHub Updates
5.1 Comment on Issue
Use @agent-fractary-work:work-manager to post comment:
{
"operation": "comment",
"issue_number": "{{issue_number}}",
"comment": "{{formatted_archive_comment}}"
}
Comment format:
✅ **FABER Workflow Archived**
All artifacts for this work have been permanently archived!
**Specifications** ({{spec_count}}):
{{#each spec_urls}}
- [{{filename}}]({{url}}) ({{size}})
{{/each}}
**Logs** ({{log_count}}):
{{#each log_urls}}
- [{{type}}: {{filename}}]({{url}}) ({{size}})
{{/each}}
**Total Size**: {{total_size}} (compressed)
**Archived**: {{timestamp}}
These artifacts are searchable via:
- `/fractary-spec:read {{issue_number}}`
- `/fractary-logs:read {{issue_number}}`
- `/fractary-logs:search "query"`
5.2 Comment on PR (if exists)
If PR URL exists from pre-checks:
{
"operation": "comment-pr",
"pr_number": "{{pr_number}}",
"comment": "{{formatted_pr_comment}}"
}
PR Comment format:
📦 **Artifacts Archived**
Specifications and logs for this PR have been archived to cloud storage.
See issue #{{issue_number}} for complete archive details.
Error handling:
if github_comment_fails:
⚠ Failed to comment on GitHub
Error: {error_message}
Archive succeeded, but GitHub comment failed.
You may want to manually comment with the archive URLs.
Continue anyway (archive is complete).
On success:
✓ GitHub updated
- Commented on issue #{{issue_number}}
{{#if pr_exists}}
- Commented on PR #{{pr_number}}
{{/if}}
Step 6: Local Cleanup
Clean up local files and commit index changes:
# Stage archive index updates
git add specs/.archive-index.json logs/.archive-index.json 2>/dev/null
# Check if there are actually changes to commit
if git diff --cached --quiet; then
echo "✅ Archive indexes (no changes to commit)"
else
# Commit archive index updates (must succeed before considering cleanup complete)
if ! git commit -m "Archive artifacts for issue #{{issue_number}}"; then
echo "❌ Failed to commit archive index updates"
echo ""
echo "Archives uploaded successfully, but local cleanup incomplete."
echo "Manual cleanup required:"
echo " git add specs/.archive-index.json logs/.archive-index.json"
echo " git commit -m 'Archive cleanup for issue #{{issue_number}}'"
exit 1
fi
echo "✅ Archive indexes committed"
fi
Note: Archived files are removed by fractary-spec and fractary-logs agents during their archive operations (Steps 3 and 4), not in this cleanup step. This step only commits the index updates.
On success:
✓ Local cleanup
- Archived files removed (by spec/log managers)
- Archive indexes committed
Step 7: Return Summary
Output completion message and return structured result:
✅ COMPLETED: Archive Workflow Skill
Issue: #{{issue_number}}
───────────────────────────────────────
Results:
- Specs archived: {{spec_count}}
- Logs archived: {{log_count}}
- Total size: {{total_size}}
- GitHub updated: {{github_updated}}
- Local cleaned: {{local_cleaned}}
Next: Archive complete! All artifacts permanently stored.
───────────────────────────────────────
Return structured result to workflow-manager:
{
"success": true,
"issue_number": "{{issue_number}}",
"specs_archived": {{spec_count}},
"logs_archived": {{log_count}},
"total_size_bytes": {{total_size}},
"archive_urls": {
"specs": [...],
"logs": [...]
},
"local_cleaned": true,
"github_updated": true
}
Exit Code Standards
To maintain consistency with the archive command, use these exit codes:
- Exit 0: Success or user cancellation
- Exit 1: Archive operation failures (spec/log upload, GitHub operations)
- Exit 2: Invalid parameters (should not occur in skill, handled by command)
- Exit 3: Configuration errors (missing .faber.config.toml)
- Exit 4: Pre-check failures (issue not closed, validation failures)
Pre-Check Failures
- Issue not found (exit 4): Exit with clear message, suggest verifying issue number
- User cancels (exit 0): Exit gracefully
- Pre-checks fail (exit 4): If not forced, exit when warnings are not accepted
- Configuration missing (exit 3): Exit with message to run /fractary-faber:init
Archive Failures
- Spec archive fails (exit 1): STOP immediately, don't proceed to logs
- Log archive fails (exit 1): Warn about partial failure, specs already safe
- Network errors (exit 1): Retry up to 3 times with exponential backoff before failing
- Cleanup fails (exit 1): Archives succeeded but local cleanup incomplete
- Partial success: Clearly show what succeeded/failed with appropriate exit code
GitHub Failures
- Comment fails: Warn but continue (archive still succeeded, don't exit)
- Authentication fails (exit 1): Show auth instructions and fail
Recovery Guidance
Always provide clear next steps:
- What to retry
- What succeeded (don't need to redo)
- Manual commands if needed
- Appropriate exit code for each failure scenario
Archive is complete when:
- ✓ Pre-checks passed or bypassed (--force)
- ✓ Specs uploaded to cloud (unless --skip-specs)
- ✓ Logs uploaded to cloud (unless --skip-logs)
- ✓ Archive indexes updated
- ✓ GitHub issue commented (or warned if failed)
- ✓ GitHub PR commented if exists (or warned if failed)
- ✓ Local files removed
- ✓ User notified of completion
- ✓ Structured result returned
Return structured JSON result to workflow-manager:
{
"success": true,
"issue_number": "123",
"specs_archived": 2,
"logs_archived": 4,
"total_size_bytes": 204800,
"archive_urls": {
"specs": [
{"filename": "spec-123-feature.md", "url": "https://...", "size": "12.3 KB"}
],
"logs": [
{"type": "session", "filename": "session-123.log", "url": "https://...", "size": "45.2 KB"}
]
},
"local_cleaned": true,
"github_updated": true,
"warnings": []
}
If errors occurred:
{
"success": false,
"issue_number": "123",
"error": "Spec archive failed",
"partial_success": {
"specs_archived": 0,
"logs_archived": 0
},
"recovery_steps": [
"Check cloud storage configuration",
"Verify network connectivity",
"Retry: /fractary-faber:archive 123"
]
}
This skill documents its work through:
- Start/End Messages: Visible progress indicators
- GitHub Comments: Permanent record on issue/PR
- Archive Indexes: Updated .archive-index.json files
- Git Commits: Archive index changes committed
- Structured Results: Returned to workflow-manager
The workflow-manager uses the structured result to:
- Update session state
- Post final notifications
- Log to FABER session history