Marketplace

archive-workflow

Archives completed FABER workflow state and artifacts to cloud storage for historical tracking and analysis

model: claude-opus-4-5

$ 설치

git clone https://github.com/fractary/claude-plugins /tmp/claude-plugins && cp -r /tmp/claude-plugins/plugins/faber/skills/archive-workflow ~/.claude/skills/claude-plugins

// tip: Run this command in your terminal to install the skill


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).

<CRITICAL_RULES> NEVER VIOLATE THESE RULES:

  1. 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)
  2. 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
  3. 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)
  4. State Management

    • ALWAYS commit archive index changes
    • ALWAYS update session state
    • ALWAYS return structured summary
    • NEVER leave indexes in inconsistent state
  5. Error Recovery

    • ALWAYS provide clear error messages
    • ALWAYS show what succeeded/failed
    • ALWAYS provide recovery steps
    • NEVER fail silently </CRITICAL_RULES>

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
}

<ERROR_HANDLING>

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

</ERROR_HANDLING>

<COMPLETION_CRITERIA>

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

</COMPLETION_CRITERIA>

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:

  1. Start/End Messages: Visible progress indicators
  2. GitHub Comments: Permanent record on issue/PR
  3. Archive Indexes: Updated .archive-index.json files
  4. Git Commits: Archive index changes committed
  5. 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