---
title: "Automation in TracerTM"
description: "Automate your traceability workflows with CLI scripting, batch operations, file watchers, Git hooks, and CI/CD integration"
---

# Automation in TracerTM

Master automation in TracerTM to streamline repetitive tasks, maintain data consistency, and integrate traceability into your development workflow.

## Overview

TracerTM provides multiple automation capabilities:

- **CLI Scripting**: Automate operations with shell scripts
- **Batch Operations**: Bulk create, update, or delete items
- **File Watchers**: Auto-index changes from `.trace/` directory
- **Git Hooks**: Trigger traceability updates on commits
- **CI/CD Integration**: Embed traceability checks in pipelines
- **Webhooks**: React to external events
- **Python SDK**: Build custom automation scripts
- **Scheduled Tasks**: Periodic maintenance and reporting

## CLI Scripting Basics

### Basic Command Patterns

The TracerTM CLI (`rtm`) supports automation through composable commands:

```bash
# Create an item and capture the ID
ITEM_ID=$(rtm item create \
  --title "Automated Feature" \
  --view FEATURE \
  --type feature \
  --status planned \
  --format json | jq -r '.id')

# Use the ID in subsequent commands
rtm link create \
  --source "$ITEM_ID" \
  --target "existing-epic-id" \
  --type implements

echo "Created feature $ITEM_ID linked to epic"
```

### Script Example: Daily Standup Report

```bash
#!/bin/bash
# daily-standup.sh - Generate daily progress report

PROJECT_ID="my-project"
YESTERDAY=$(date -d "yesterday" +%Y-%m-%d)

# Export completed items from yesterday
rtm item list \
  --project "$PROJECT_ID" \
  --status completed \
  --updated-since "$YESTERDAY" \
  --format json > /tmp/completed.json

# Count by type
FEATURES=$(jq '[.[] | select(.type == "feature")] | length' /tmp/completed.json)
BUGS=$(jq '[.[] | select(.type == "bug")] | length' /tmp/completed.json)

# Generate report
cat << EOF
Daily Standup Report - $(date +%Y-%m-%d)
=====================================
Completed Yesterday:
  - Features: $FEATURES
  - Bugs: $BUGS

Top Items:
EOF

jq -r '.[] | "  - [\(.type)] \(.title)"' /tmp/completed.json | head -10

# Send to Slack (optional)
if [ -n "$SLACK_WEBHOOK" ]; then
  curl -X POST "$SLACK_WEBHOOK" \
    -H 'Content-Type: application/json' \
    -d "{\"text\":\"$(cat /tmp/standup.txt)\"}"
fi
```

### Error Handling in Scripts

```bash
#!/bin/bash
# robust-automation.sh - Script with proper error handling

set -euo pipefail  # Exit on error, undefined vars, pipe failures

# Trap errors and cleanup
cleanup() {
  local exit_code=$?
  if [ $exit_code -ne 0 ]; then
    echo "ERROR: Script failed with exit code $exit_code" >&2
    # Rollback or notification logic here
  fi
  # Cleanup temp files
  rm -f /tmp/rtm-*.tmp
}
trap cleanup EXIT

# Function with error handling
create_item_safe() {
  local title="$1"
  local view="$2"

  if ! rtm item create --title "$title" --view "$view" 2>/tmp/rtm-error.log; then
    echo "ERROR: Failed to create item '$title'" >&2
    cat /tmp/rtm-error.log >&2
    return 1
  fi

  echo "Created: $title"
  return 0
}

# Use the function
create_item_safe "Test Feature" "FEATURE" || exit 1
```

## Batch Operations

### Bulk Create from CSV

```bash
# bulk-create.sh - Create items from CSV file

# CSV format: title,view,type,status,priority,owner
# Example: "User Login,FEATURE,feature,planned,high,alice"

CSV_FILE="$1"

if [ ! -f "$CSV_FILE" ]; then
  echo "Usage: $0 <csv-file>"
  exit 1
fi

# Read CSV and create items (skip header)
tail -n +2 "$CSV_FILE" | while IFS=, read -r title view type status priority owner; do
  echo "Creating: $title"

  rtm item create \
    --title "$title" \
    --view "$view" \
    --type "$type" \
    --status "$status" \
    --priority "$priority" \
    --owner "$owner" || echo "FAILED: $title"

  # Rate limiting
  sleep 0.1
done

echo "Bulk creation complete"
```

### Bulk Update with Preview

```bash
# Use the built-in bulk update with preview
rtm item bulk-update-preview \
  --filter view=TEST \
  --filter status=draft \
  --set status=ready \
  --set priority=high \
  --limit 10

# Review the preview, then execute
rtm item bulk-update \
  --filter view=TEST \
  --filter status=draft \
  --set status=ready \
  --set priority=high \
  --confirm
```

### Bulk Export and Transform

```bash
#!/bin/bash
# export-transform-import.sh - Export, modify, and re-import

PROJECT_ID="my-project"

# Export to JSON
rtm export json --project "$PROJECT_ID" > export.json

# Transform with jq (e.g., update all TEST items priority)
jq '.items |= map(
  if .view == "TEST" then
    .priority = "critical"
  else
    .
  end
)' export.json > transformed.json

# Create backup
cp export.json "backup-$(date +%Y%m%d-%H%M%S).json"

# Re-import (careful!)
# Note: This is a hypothetical import command
# rtm import json --file transformed.json --merge
```

## File Watcher Automation

### Basic File Watching

TracerTM includes a file watcher that auto-indexes changes from the `.trace/` directory:

```bash
# Start watching current project
rtm watch

# Watch with auto-sync to remote
rtm watch --auto-sync

# Watch specific project
rtm watch --path /path/to/project

# Custom debounce delay (milliseconds)
rtm watch --debounce 1000
```

### Watch Output

```
Watching: /home/user/my-project/.trace
Debounce: 500ms | Auto-sync: disabled

Status: Running
┌──────────────┬───────────┬──────────────┬─────────────┐
│ Metric       │ Value     │ Last Event   │ Status      │
├──────────────┼───────────┼──────────────┼─────────────┤
│ Events       │ 142       │ 2s ago       │ Active      │
│ Items        │ 89        │ 2s ago       │ Indexed     │
│ Links        │ 53        │ 5s ago       │ Indexed     │
│ Config       │ 0         │ Never        │ -           │
└──────────────┴───────────┴──────────────┴─────────────┘

Press Ctrl+C to stop...
```

### Automated Sync on File Changes

```bash
#!/bin/bash
# watch-and-sync.sh - Watch files and sync on changes

# Start file watcher in background
rtm watch --auto-sync &
WATCH_PID=$!

# Ensure cleanup on exit
trap "kill $WATCH_PID 2>/dev/null" EXIT

echo "File watcher started (PID: $WATCH_PID)"
echo "Making changes to .trace/ will auto-sync to remote"

# Keep running
wait $WATCH_PID
```

### Integration with Editors

For editor integration, create a watch script that runs in the background:

```bash
# .trace/watch.sh
#!/bin/bash
# Auto-start file watcher for this project

WATCH_LOG=".trace/.meta/watch.log"
WATCH_PID=".trace/.meta/watch.pid"

# Check if already running
if [ -f "$WATCH_PID" ] && kill -0 $(cat "$WATCH_PID") 2>/dev/null; then
  echo "Watcher already running (PID: $(cat $WATCH_PID))"
  exit 0
fi

# Start watcher
nohup rtm watch --path . > "$WATCH_LOG" 2>&1 &
echo $! > "$WATCH_PID"

echo "Watcher started (PID: $(cat $WATCH_PID))"
```

## Git Hooks Integration

### Pre-Commit Hook: Validate Traceability

```bash
#!/bin/bash
# .git/hooks/pre-commit - Ensure all code changes have traceability

set -e

# Check if we're in a TracerTM project
if [ ! -d ".trace" ]; then
  exit 0  # Not a TracerTM project, skip
fi

echo "Validating traceability..."

# Get list of modified code files
CHANGED_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep -E '\.(py|js|ts|tsx)$' || true)

if [ -z "$CHANGED_FILES" ]; then
  echo "No code files changed, skipping traceability check"
  exit 0
fi

# Check if there are TEST items for modified files
MISSING_TESTS=""

for file in $CHANGED_FILES; do
  # Check if file has associated test traceability
  TEST_COUNT=$(rtm item list \
    --view CODE \
    --filter "metadata.file_path=$file" \
    --format json 2>/dev/null | jq 'length')

  if [ "$TEST_COUNT" -eq 0 ]; then
    MISSING_TESTS="${MISSING_TESTS}\n  - $file"
  fi
done

if [ -n "$MISSING_TESTS" ]; then
  echo "WARNING: The following files lack traceability:"
  echo -e "$MISSING_TESTS"
  echo ""
  echo "Consider adding traceability items before committing."
  echo "To bypass this check, use: git commit --no-verify"
  exit 1
fi

echo "Traceability check passed!"
exit 0
```

### Post-Commit Hook: Auto-Link Commits

```bash
#!/bin/bash
# .git/hooks/post-commit - Auto-link commit to items mentioned in message

COMMIT_MSG=$(git log -1 --pretty=%B)
COMMIT_SHA=$(git rev-parse HEAD)
COMMIT_SHORT=$(git rev-parse --short HEAD)

# Extract item IDs from commit message (e.g., REQ-123, FEAT-456)
ITEM_IDS=$(echo "$COMMIT_MSG" | grep -oE '[A-Z]+-[0-9]+' || true)

if [ -z "$ITEM_IDS" ]; then
  exit 0  # No items mentioned
fi

echo "Linking commit $COMMIT_SHORT to items..."

for item_id in $ITEM_IDS; do
  # Find item in database
  ITEM_EXISTS=$(rtm item get "$item_id" --format json 2>/dev/null || echo "null")

  if [ "$ITEM_EXISTS" != "null" ]; then
    # Create CODE item for this commit
    COMMIT_ITEM=$(rtm item create \
      --title "Commit: $COMMIT_SHORT" \
      --view CODE \
      --type commit \
      --description "$COMMIT_MSG" \
      --metadata "{\"sha\":\"$COMMIT_SHA\",\"short\":\"$COMMIT_SHORT\"}" \
      --format json | jq -r '.id')

    # Link commit to mentioned item
    rtm link create \
      --source "$COMMIT_ITEM" \
      --target "$item_id" \
      --type implements

    echo "  ✓ Linked to $item_id"
  fi
done
```

### Install Git Hooks

```bash
# install-hooks.sh - Install TracerTM Git hooks

HOOKS_DIR=".git/hooks"

# Pre-commit hook
cat > "$HOOKS_DIR/pre-commit" << 'EOF'
#!/bin/bash
# TracerTM pre-commit hook
# Add your pre-commit logic here
EOF

chmod +x "$HOOKS_DIR/pre-commit"

# Post-commit hook
cat > "$HOOKS_DIR/post-commit" << 'EOF'
#!/bin/bash
# TracerTM post-commit hook
# Add your post-commit logic here
EOF

chmod +x "$HOOKS_DIR/post-commit"

echo "Git hooks installed successfully!"
```

## CI/CD Automation Patterns

### GitHub Actions Workflow

```yaml
# .github/workflows/traceability.yml
name: Traceability Checks

on:
  pull_request:
    branches: [main, develop]
  push:
    branches: [main, develop]

jobs:
  traceability:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: '3.11'

      - name: Install TracerTM
        run: |
          pip install tracertm
          rtm config init --database sqlite:///tracertm.db

      - name: Validate Traceability
        run: |
          # Check that all features have test coverage
          UNCOVERED=$(rtm item list \
            --view FEATURE \
            --filter status!=draft \
            --no-links-to TEST \
            --format json | jq 'length')

          if [ "$UNCOVERED" -gt 0 ]; then
            echo "ERROR: $UNCOVERED features lack test coverage"
            exit 1
          fi

      - name: Generate Coverage Report
        run: |
          rtm report coverage \
            --source FEATURE \
            --target TEST \
            --format markdown > coverage-report.md

      - name: Comment on PR
        if: github.event_name == 'pull_request'
        uses: actions/github-script@v6
        with:
          script: |
            const fs = require('fs');
            const report = fs.readFileSync('coverage-report.md', 'utf8');

            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: `## Traceability Coverage Report\n\n${report}`
            });

      - name: Upload Report
        uses: actions/upload-artifact@v3
        with:
          name: traceability-report
          path: coverage-report.md
```

### GitLab CI Pipeline

```yaml
# .gitlab-ci.yml
stages:
  - validate
  - report

variables:
  RTM_DB: "sqlite:///tracertm.db"

traceability_check:
  stage: validate
  image: python:3.11
  before_script:
    - pip install tracertm
    - rtm config init --database $RTM_DB
  script:
    # Validate all API endpoints have tests
    - |
      MISSING_TESTS=$(rtm item list \
        --view API \
        --no-links-to TEST \
        --format json | jq -r '.[] | .id + ": " + .title')

      if [ -n "$MISSING_TESTS" ]; then
        echo "ERROR: API endpoints missing tests:"
        echo "$MISSING_TESTS"
        exit 1
      fi

    # Check for orphaned items
    - rtm validate --check-orphans --fail-on-error
  only:
    - merge_requests
    - main

coverage_report:
  stage: report
  image: python:3.11
  before_script:
    - pip install tracertm
    - rtm config init --database $RTM_DB
  script:
    - rtm report matrix --format html > coverage.html
  artifacts:
    paths:
      - coverage.html
    expire_in: 1 week
  only:
    - main
```

### Jenkins Pipeline

```groovy
// Jenkinsfile
pipeline {
    agent any

    environment {
        RTM_DB = 'sqlite:///tracertm.db'
    }

    stages {
        stage('Setup') {
            steps {
                sh 'pip install tracertm'
                sh "rtm config init --database ${RTM_DB}"
            }
        }

        stage('Validate Traceability') {
            steps {
                script {
                    def uncovered = sh(
                        script: '''
                            rtm item list \
                                --view FEATURE \
                                --status planned \
                                --no-links-to TEST \
                                --format json | jq 'length'
                        ''',
                        returnStdout: true
                    ).trim()

                    if (uncovered.toInteger() > 0) {
                        error("${uncovered} features lack test coverage")
                    }
                }
            }
        }

        stage('Generate Reports') {
            steps {
                sh 'rtm report coverage --format json > coverage.json'
                sh 'rtm report matrix --format html > matrix.html'
            }
        }

        stage('Archive') {
            steps {
                archiveArtifacts artifacts: '*.html,*.json', fingerprint: true
            }
        }
    }

    post {
        failure {
            emailext(
                subject: "Traceability Check Failed: ${env.JOB_NAME}",
                body: "Build ${env.BUILD_NUMBER} failed traceability validation",
                to: "${env.CHANGE_AUTHOR_EMAIL}"
            )
        }
    }
}
```

## Webhook-Triggered Automation

### Setting Up Webhooks

```bash
# Configure webhook endpoint
rtm config set webhook_url "https://api.example.com/webhooks/tracertm"
rtm config set webhook_secret "your-secret-key"
rtm config set webhook_events "item.created,item.updated,link.created"
```

### Webhook Handler Example

```python
# webhook_handler.py - Flask webhook receiver
from flask import Flask, request, jsonify
import hmac
import hashlib
from tracertm.api.client import TraceRTMClient

app = Flask(__name__)
WEBHOOK_SECRET = "your-secret-key"

def verify_signature(payload, signature):
    """Verify webhook signature."""
    expected = hmac.new(
        WEBHOOK_SECRET.encode(),
        payload,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, signature)

@app.route('/webhooks/tracertm', methods=['POST'])
def handle_webhook():
    # Verify signature
    signature = request.headers.get('X-TracerTM-Signature')
    if not verify_signature(request.data, signature):
        return jsonify({'error': 'Invalid signature'}), 401

    event = request.json
    event_type = event['type']

    # Initialize client
    client = TraceRTMClient(agent_name="webhook-handler")

    # Handle different event types
    if event_type == 'item.created':
        handle_item_created(client, event['data'])
    elif event_type == 'item.updated':
        handle_item_updated(client, event['data'])
    elif event_type == 'link.created':
        handle_link_created(client, event['data'])

    return jsonify({'status': 'processed'}), 200

def handle_item_created(client, data):
    """Handle item creation webhook."""
    item_id = data['id']
    view = data['view']

    # Auto-create test placeholder when feature is created
    if view == 'FEATURE':
        test_item = client.create_item(
            title=f"Tests for {data['title']}",
            view='TEST',
            item_type='test_suite',
            status='planned'
        )

        # Link feature to test
        client.create_link(
            source=item_id,
            target=test_item['id'],
            link_type='tested_by'
        )

def handle_item_updated(client, data):
    """Handle item update webhook."""
    # Notify team on status changes
    if 'status' in data.get('changes', {}):
        old_status = data['changes']['status']['old']
        new_status = data['changes']['status']['new']

        # Send notification (pseudo-code)
        send_notification(
            f"Item {data['id']} changed: {old_status} → {new_status}"
        )

def handle_link_created(client, data):
    """Handle link creation webhook."""
    # Update metrics when links are created
    pass

if __name__ == '__main__':
    app.run(port=8080)
```

### Webhook Testing Script

```bash
#!/bin/bash
# test-webhook.sh - Test webhook configuration

WEBHOOK_URL="https://api.example.com/webhooks/tracertm"
SECRET="your-secret-key"

# Sample event payload
PAYLOAD=$(cat << 'EOF'
{
  "type": "item.created",
  "timestamp": "2024-01-15T10:30:00Z",
  "data": {
    "id": "feat-123",
    "title": "New Feature",
    "view": "FEATURE",
    "type": "feature",
    "status": "planned"
  }
}
EOF
)

# Calculate signature
SIGNATURE=$(echo -n "$PAYLOAD" | openssl dgst -sha256 -hmac "$SECRET" | awk '{print $2}')

# Send webhook
curl -X POST "$WEBHOOK_URL" \
  -H "Content-Type: application/json" \
  -H "X-TracerTM-Signature: $SIGNATURE" \
  -d "$PAYLOAD"
```

## Scheduled Tasks

### Cron-Based Automation

```bash
# Add to crontab: crontab -e

# Daily backup at 2 AM
0 2 * * * cd /path/to/project && rtm export json --output "backup-$(date +\%Y\%m\%d).json"

# Weekly coverage report on Monday at 9 AM
0 9 * * 1 cd /path/to/project && rtm report coverage --email team@example.com

# Hourly sync to remote
0 * * * * cd /path/to/project && rtm sync push >> /var/log/rtm-sync.log 2>&1

# Daily cleanup of old backups (keep last 30 days)
0 3 * * * find /path/to/backups -name "backup-*.json" -mtime +30 -delete
```

### Systemd Timer (Linux)

```ini
# /etc/systemd/system/rtm-sync.timer
[Unit]
Description=TracerTM Sync Timer
Requires=rtm-sync.service

[Timer]
OnBootSec=5min
OnUnitActiveSec=1h

[Install]
WantedBy=timers.target
```

```ini
# /etc/systemd/system/rtm-sync.service
[Unit]
Description=TracerTM Sync Service
After=network.target

[Service]
Type=oneshot
User=youruser
WorkingDirectory=/path/to/project
ExecStart=/usr/local/bin/rtm sync push
StandardOutput=journal
StandardError=journal
```

Enable and start:

```bash
sudo systemctl enable rtm-sync.timer
sudo systemctl start rtm-sync.timer
sudo systemctl status rtm-sync.timer
```

## Python SDK for Automation

### Basic Client Usage

```python
# automation_script.py
from tracertm.api.client import TraceRTMClient

# Initialize client
client = TraceRTMClient(agent_name="automation-script")

# Create items programmatically
feature = client.create_item(
    title="User Authentication",
    view="FEATURE",
    item_type="feature",
    status="planned",
    priority="high",
    owner="alice",
    metadata={
        "epic": "user-management",
        "sprint": "2024-01"
    }
)

print(f"Created feature: {feature['id']}")

# Query items
features = client.query_items(
    view="FEATURE",
    filters={"status": "planned", "priority": "high"}
)

print(f"Found {len(features)} high-priority planned features")

# Bulk operations
for item in features:
    client.update_item(
        item_id=item['id'],
        updates={"status": "in_progress"}
    )
    print(f"Updated {item['id']} to in_progress")
```

### Advanced Automation Example

```python
# auto_test_coverage.py - Ensure all features have test coverage
from tracertm.api.client import TraceRTMClient
import logging

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

class TestCoverageBot:
    def __init__(self):
        self.client = TraceRTMClient(agent_name="test-coverage-bot")

    def ensure_test_coverage(self):
        """Ensure all features have corresponding tests."""
        # Get all features
        features = self.client.query_items(
            view="FEATURE",
            filters={"status": ["planned", "in_progress", "completed"]}
        )

        logger.info(f"Checking {len(features)} features for test coverage")

        created_tests = 0

        for feature in features:
            # Check if feature has test links
            links = self.client.get_item_links(feature['id'])
            has_tests = any(
                link['target_view'] == 'TEST'
                for link in links
            )

            if not has_tests:
                logger.warning(
                    f"Feature {feature['id']} lacks tests, creating..."
                )

                # Create test suite
                test = self.client.create_item(
                    title=f"Test Suite: {feature['title']}",
                    view="TEST",
                    item_type="test_suite",
                    status="planned",
                    description=f"Tests for {feature['title']}",
                    metadata={
                        "auto_generated": True,
                        "feature_id": feature['id']
                    }
                )

                # Link feature to test
                self.client.create_link(
                    source=feature['id'],
                    target=test['id'],
                    link_type="tested_by"
                )

                created_tests += 1
                logger.info(f"Created test {test['id']} for feature {feature['id']}")

        logger.info(f"Test coverage check complete. Created {created_tests} new tests.")

        return {
            'total_features': len(features),
            'tests_created': created_tests
        }

if __name__ == '__main__':
    bot = TestCoverageBot()
    result = bot.ensure_test_coverage()
    print(f"Results: {result}")
```

### Data Migration Script

```python
# migrate_data.py - Migrate data between projects
from tracertm.api.client import TraceRTMClient
import json

def migrate_features(source_project_id, target_project_id):
    """Migrate features from one project to another."""
    client = TraceRTMClient(agent_name="migration-bot")

    # Export from source
    print(f"Exporting from {source_project_id}...")
    source_items = client.query_items(
        project_id=source_project_id,
        view="FEATURE"
    )

    print(f"Found {len(source_items)} features to migrate")

    # ID mapping for links
    id_mapping = {}

    # Import to target
    print(f"Importing to {target_project_id}...")
    for item in source_items:
        old_id = item['id']

        # Create in target project
        new_item = client.create_item(
            project_id=target_project_id,
            title=item['title'],
            view=item['view'],
            item_type=item['type'],
            status=item['status'],
            priority=item.get('priority'),
            owner=item.get('owner'),
            description=item.get('description'),
            metadata=item.get('metadata', {})
        )

        id_mapping[old_id] = new_item['id']
        print(f"Migrated {old_id} → {new_item['id']}")

    # Migrate links
    print("Migrating links...")
    for old_id, new_id in id_mapping.items():
        links = client.get_item_links(old_id, project_id=source_project_id)

        for link in links:
            if link['target'] in id_mapping:
                client.create_link(
                    source=new_id,
                    target=id_mapping[link['target']],
                    link_type=link['type'],
                    project_id=target_project_id
                )

    print(f"Migration complete. Migrated {len(id_mapping)} items.")

    # Save mapping for reference
    with open('migration_mapping.json', 'w') as f:
        json.dump(id_mapping, f, indent=2)

if __name__ == '__main__':
    migrate_features('old-project', 'new-project')
```

## Best Practices for Automation

### 1. Idempotency

Ensure scripts can run multiple times without causing issues:

```bash
#!/bin/bash
# idempotent-script.sh

ITEM_ID="my-feature-123"

# Check if item exists before creating
if ! rtm item get "$ITEM_ID" &>/dev/null; then
  rtm item create --id "$ITEM_ID" --title "My Feature" --view FEATURE
  echo "Created $ITEM_ID"
else
  echo "$ITEM_ID already exists, skipping creation"
fi
```

### 2. Logging and Auditing

```python
# automated_task.py
import logging
from datetime import datetime

# Configure logging
logging.basicConfig(
    filename=f'automation-{datetime.now():%Y%m%d}.log',
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)

logger = logging.getLogger(__name__)

def automated_task():
    logger.info("Starting automated task")

    try:
        # Your automation logic
        result = perform_operation()
        logger.info(f"Task completed successfully: {result}")
    except Exception as e:
        logger.error(f"Task failed: {e}", exc_info=True)
        raise

if __name__ == '__main__':
    automated_task()
```

### 3. Rate Limiting

```python
# rate_limited_bot.py
import time
from tracertm.api.client import TraceRTMClient

class RateLimitedBot:
    def __init__(self, requests_per_second=10):
        self.client = TraceRTMClient(agent_name="rate-limited-bot")
        self.delay = 1.0 / requests_per_second

    def bulk_create(self, items):
        for item in items:
            self.client.create_item(**item)
            time.sleep(self.delay)  # Rate limiting
```

### 4. Error Recovery

```python
# resilient_automation.py
from tracertm.api.client import TraceRTMClient
import time

def retry_with_backoff(func, max_retries=3, initial_delay=1):
    """Retry function with exponential backoff."""
    for attempt in range(max_retries):
        try:
            return func()
        except Exception as e:
            if attempt == max_retries - 1:
                raise

            delay = initial_delay * (2 ** attempt)
            print(f"Attempt {attempt + 1} failed: {e}")
            print(f"Retrying in {delay}s...")
            time.sleep(delay)

# Usage
client = TraceRTMClient(agent_name="resilient-bot")

def create_item():
    return client.create_item(
        title="Important Feature",
        view="FEATURE",
        item_type="feature"
    )

item = retry_with_backoff(create_item)
```

### 5. Testing Automation Scripts

```bash
# test_automation.sh - Test automation in dry-run mode

# Set dry-run mode
export RTM_DRY_RUN=true

# Run automation script
./my-automation-script.sh

# Check results without committing
if [ $? -eq 0 ]; then
  echo "Dry run successful, execute for real? (y/n)"
  read -r response

  if [ "$response" = "y" ]; then
    unset RTM_DRY_RUN
    ./my-automation-script.sh
  fi
fi
```

### 6. Monitoring and Alerts

```python
# monitored_automation.py
from tracertm.api.client import TraceRTMClient
import requests

SLACK_WEBHOOK = "https://hooks.slack.com/services/YOUR/WEBHOOK/URL"

def send_alert(message, level="info"):
    """Send alert to Slack."""
    color = {"info": "good", "warning": "warning", "error": "danger"}[level]

    requests.post(SLACK_WEBHOOK, json={
        "attachments": [{
            "color": color,
            "text": message
        }]
    })

def monitored_task():
    try:
        client = TraceRTMClient(agent_name="monitored-bot")

        # Your automation logic
        result = perform_operations(client)

        send_alert(f"Automation completed: {result}", "info")

    except Exception as e:
        send_alert(f"Automation failed: {e}", "error")
        raise

if __name__ == '__main__':
    monitored_task()
```

## Summary

TracerTM automation enables you to:

- **Streamline Workflows**: Automate repetitive traceability tasks
- **Ensure Consistency**: Enforce traceability policies via CI/CD
- **React to Events**: Trigger actions based on changes (webhooks, file watching)
- **Scale Operations**: Handle bulk updates efficiently
- **Integrate Deeply**: Embed traceability in your development process

Start with simple CLI scripts, then progress to Python SDK automation and CI/CD integration as your needs grow.

## Next Steps

- [API Integration](/docs/wiki/tutorials/intermediate/api-integration) - Integrate TracerTM with external systems
- [Custom Reports](/docs/wiki/tutorials/intermediate/reporting) - Create custom traceability reports
- [Python SDK Reference](/docs/api-reference/python-sdk) - Complete SDK documentation
- [CLI Reference](/docs/api-reference/cli) - All CLI commands
