# Task-Level Analysis

Jobs are bundles of tasks-and AI doesn't automate jobs, it automates tasks. This guide shows how to work with Cubit's task-level data to understand exactly which activities within a role are most (and least) vulnerable.

**Tier Required:** Professional (scores) or Enterprise (with explanations)

## Why Task-Level Analysis?

A "Financial Analyst" performs:

* Data gathering (highly automatable)
* Model building (partially automatable)
* Client relationship management (protected)

Job-level scores average these together. Task-level analysis reveals the internal structure.

## Fetching Task Data

```python
from cubit import CubitClient

client = CubitClient("cubit_your_key")

# Get tasks for Software Developers
tasks = client.get_job_tasks(
    "15-1252.00",
    sort_by="ai_exposure_potential",
    sort_order="desc",
    limit=50,
    include_explanations=True
)

print(f"Job: {tasks['title']}")
print(f"Total tasks: {tasks['task_count']}\n")
```

## Understanding Task Structure

Each task includes:

```python
task = tasks["tasks"][0]

# The work activity description
print(f"Task: {task['task']}")

# How important this task is to the job (1-5)
print(f"Importance: {task['importance']}")

# What percentage of workers perform it
print(f"Relevance: {task['relevance']}%")

# Four foundational dimension scores (0-10)
print(f"Procedural: {task['dimensions']['procedural']}")
print(f"Digital: {task['dimensions']['digitization']}")
print(f"Physical: {task['dimensions']['physicality']}")
print(f"Relational: {task['dimensions']['socio_emotional']}")

# Derived pillar scores (0-1)
print(f"Structural Exposure: {task['pillars']['structural_exposure']:.0%}")
print(f"Human Necessity: {task['pillars']['human_imperative']:.0%}")
print(f"AI Exposure Potential: {task['pillars']['ai_exposure_potential']:.0%}")

# Strategic classification
print(f"Quadrant: {task['quadrant']}")

# Explanations for each dimension score
print(f"\nWhy this procedural score?")
print(f"  {task['explanations']['procedural']}")
```

## Analyzing Task Distribution

### By Quadrant

```python
from collections import Counter

tasks = client.get_job_tasks("15-1252.00", limit=100)

# Count tasks by quadrant
quadrant_counts = Counter(t["quadrant"] for t in tasks["tasks"])

print(f"Task Distribution for {tasks['title']}:\n")
for quadrant, count in quadrant_counts.most_common():
    pct = count / len(tasks["tasks"]) * 100
    bar = "#" * int(pct / 5)
    print(f"  {quadrant:<15} {bar} {count} tasks ({pct:.0f}%)")
```

**Output:**

```
Task Distribution for Software Developers:

  automation      ######### 9 tasks (47%)
  transitional      ###### 6 tasks (32%)
  protected       #### 4 tasks (21%)
```

### By Exposure Level

```python
# Segment tasks by AI exposure potential
high_exposure = [t for t in tasks["tasks"] if t["pillars"]["ai_exposure_potential"] > 0.6]
medium_exposure = [t for t in tasks["tasks"] if 0.4 <= t["pillars"]["ai_exposure_potential"] <= 0.6]
low_exposure = [t for t in tasks["tasks"] if t["pillars"]["ai_exposure_potential"] < 0.4]

print(f"High Exposure ({len(high_exposure)} tasks):")
for t in high_exposure[:3]:
    print(f"  - {t['task'][:70]}...")

print(f"\nLow Exposure ({len(low_exposure)} tasks):")
for t in low_exposure[:3]:
    print(f"  - {t['task'][:70]}...")
```

## Identifying Vulnerable vs. Protected Tasks

### Most Vulnerable Tasks

```python
tasks = client.get_job_tasks(
    "15-1252.00",
    sort_by="ai_exposure_potential",
    sort_order="desc",
    limit=5
)

print(" Most AI-Exposed Tasks:\n")
for task in tasks["tasks"]:
    print(f"- {task['task']}")
    print(f"  Exposure: {task['pillars']['ai_exposure_potential']:.0%}")
    print(f"  Quadrant: {task['quadrant']}")
    print(f"  Why: {task['explanations']['procedural'][:100]}...")
    print()
```

### Most Protected Tasks

```python
tasks = client.get_job_tasks(
    "15-1252.00",
    sort_by="human_imperative",  # Sort by human necessity
    sort_order="desc",
    limit=5
)

print(" Most Protected Tasks:\n")
for task in tasks["tasks"]:
    print(f"- {task['task']}")
    print(f"  Human Necessity: {task['pillars']['human_imperative']:.0%}")
    print(f"  Quadrant: {task['quadrant']}")
    print()
```

## Dimension Analysis

### Understanding Why Tasks Score Differently

```python
tasks = client.get_job_tasks("29-1141.00")  # Registered Nurses

# Compare two tasks with different profiles
for task in tasks["tasks"][:2]:
    print(f"\n{'='*60}")
    print(f"Task: {task['task'][:80]}...")
    print(f"\nDimension Scores:")
    print(f"  Procedural:    {task['dimensions']['procedural']}/10 - {task['explanations']['procedural'][:60]}...")
    print(f"  Digital:       {task['dimensions']['digitization']}/10 - {task['explanations']['digitization'][:60]}...")
    print(f"  Physical:      {task['dimensions']['physicality']}/10 - {task['explanations']['physicality'][:60]}...")
    print(f"  Relational:    {task['dimensions']['socio_emotional']}/10 - {task['explanations']['socio_emotional'][:60]}...")
```

### Visualizing Dimension Profiles

```python
import matplotlib.pyplot as plt
import numpy as np

tasks = client.get_job_tasks("29-1141.00", limit=20)

# Aggregate dimension averages
dims = ["procedural", "digitization", "physicality", "socio_emotional"]
averages = [
    np.mean([t["dimensions"][d] for t in tasks["tasks"]])
    for d in dims
]

# Radar chart
angles = np.linspace(0, 2 * np.pi, len(dims), endpoint=False).tolist()
averages += averages[:1]  # Close the polygon
angles += angles[:1]

fig, ax = plt.subplots(figsize=(6, 6), subplot_kw=dict(polar=True))
ax.plot(angles, averages)
ax.fill(angles, averages, alpha=0.25)
ax.set_xticks(angles[:-1])
ax.set_xticklabels(["Procedural", "Digital", "Physical", "Relational"])
ax.set_ylim(0, 10)
ax.set_title(f"Dimension Profile: {tasks['title']}")
plt.show()
```

## Building a Task Breakdown UI

### React Component

```tsx
interface Task {
  task_id: string;
  task: string;
  quadrant: string;
  pillars: {
    ai_exposure_potential: number;
    human_imperative: number;
  };
  dimensions: {
    procedural: number;
    digitization: number;
    physicality: number;
    socio_emotional: number;
  };
  explanations?: {
    procedural: string;
    digitization: string;
    physicality: string;
    socio_emotional: string;
  };
}

function TaskList({ socCode }: { socCode: string }) {
  const [tasks, setTasks] = useState<Task[]>([]);
  const [sortBy, setSortBy] = useState('ai_exposure_potential');
  const [expandedTask, setExpandedTask] = useState<string | null>(null);

  useEffect(() => {
    fetch(`/api/jobs/${socCode}/tasks?sort_by=${sortBy}`)
      .then(r => r.json())
      .then(data => setTasks(data.tasks));
  }, [socCode, sortBy]);

  return (
    <div>
      <div className="mb-4">
        <label>Sort by: </label>
        <select value={sortBy} onChange={e => setSortBy(e.target.value)}>
          <option value="ai_exposure_potential">AI Exposure (High->Low)</option>
          <option value="human_imperative">Human Necessity (High->Low)</option>
          <option value="importance">Importance</option>
        </select>
      </div>

      <div className="space-y-2">
        {tasks.map(task => (
          <TaskCard 
            key={task.task_id} 
            task={task}
            expanded={expandedTask === task.task_id}
            onToggle={() => setExpandedTask(
              expandedTask === task.task_id ? null : task.task_id
            )}
          />
        ))}
      </div>
    </div>
  );
}

function TaskCard({ task, expanded, onToggle }: { 
  task: Task; 
  expanded: boolean;
  onToggle: () => void;
}) {
  const quadrantColors = {
    automation: 'border-red-400 bg-red-50',
    augmentation: 'border-yellow-400 bg-yellow-50',
    protected: 'border-green-400 bg-green-50',
    transitional: 'border-gray-400 bg-gray-50',
  };

  return (
    <div className={`border-l-4 p-4 rounded ${quadrantColors[task.quadrant]}`}>
      <div className="flex justify-between items-start cursor-pointer" onClick={onToggle}>
        <div className="flex-1">
          <p className="font-medium">{task.task}</p>
          <div className="mt-2 flex gap-4 text-sm text-gray-600">
            <span>Exposure: {(task.pillars.ai_exposure_potential * 100).toFixed(0)}%</span>
            <span>Human: {(task.pillars.human_imperative * 100).toFixed(0)}%</span>
            <span className="capitalize">{task.quadrant}</span>
          </div>
        </div>
        <span>{expanded ? 'v' : '>'}</span>
      </div>

      {expanded && task.explanations && (
        <div className="mt-4 grid grid-cols-2 gap-4 text-sm">
          <div>
            <strong>Procedural ({task.dimensions.procedural}/10)</strong>
            <p className="text-gray-600">{task.explanations.procedural}</p>
          </div>
          <div>
            <strong>Digital ({task.dimensions.digitization}/10)</strong>
            <p className="text-gray-600">{task.explanations.digitization}</p>
          </div>
          <div>
            <strong>Physical ({task.dimensions.physicality}/10)</strong>
            <p className="text-gray-600">{task.explanations.physicality}</p>
          </div>
          <div>
            <strong>Relational ({task.dimensions.socio_emotional}/10)</strong>
            <p className="text-gray-600">{task.explanations.socio_emotional}</p>
          </div>
        </div>
      )}
    </div>
  );
}
```

## Use Cases

### Workforce Transformation Planning

Identify which tasks to automate, augment, or elevate:

```python
tasks = client.get_job_tasks("43-4051.00")  # Customer Service Reps

automate = []
augment = []
elevate = []

for task in tasks["tasks"]:
    if task["quadrant"] == "automation":
        automate.append(task)
    elif task["quadrant"] == "augmentation":
        augment.append(task)
    else:
        elevate.append(task)

print("AUTOMATE (offload to AI):")
for t in automate:
    print(f"  - {t['task'][:60]}...")

print("\nAUGMENT (human-AI collaboration):")
for t in augment:
    print(f"  - {t['task'][:60]}...")

print("\nELEVATE (increase human focus):")
for t in elevate:
    print(f"  - {t['task'][:60]}...")
```

### Training Needs Analysis

Find protected tasks to train workers on:

```python
# For a role facing automation, identify protected tasks to emphasize
tasks = client.get_job_tasks("43-3031.00")  # Bookkeeping Clerks

protected_skills = []
for task in tasks["tasks"]:
    if task["quadrant"] in ["protected", "augmentation"]:
        if task["dimensions"]["socio_emotional"] > 5:
            protected_skills.append(task)

print("Tasks requiring human skills (train workers on these):")
for t in protected_skills:
    print(f"  - {t['task'][:70]}...")
    print(f"    Relational score: {t['dimensions']['socio_emotional']}/10")
```

## Next Steps

* [Career Transitions](/guides/career-transitions.md) - Find paths from exposed to protected roles
* [Custom Scoring](/guides/custom-scoring.md) - Apply your own dimension weights
* [API Reference: Tasks](/api-reference/jobs.md#get-jobssoc_codetasks) - Full endpoint docs


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.maidenlabs.tools/guides/task-analysis.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
