Unified inbox processor - handles ALL content types (clippings, transcriptions, VTT files, attachments) with parallel subagents and single-table review. Routes to appropriate creator based on proposed_template.
From para-obsidiannpx claudepluginhub nathanvale/side-quest-marketplace-old --plugin para-obsidianThis skill is limited to using the following tools:
references/architecture.mdreferences/context-isolation.mdreferences/enrichment-strategies.mdreferences/execution-phases.mdreferences/output-templates.mdreferences/proposal-schema.mdreferences/stakeholder-bootstrap.mdreferences/subagent-prompts.mdreferences/task-patterns.mdDesigns and optimizes AI agent action spaces, tool definitions, observation formats, error recovery, and context for higher task completion rates.
Implements structured self-debugging workflow for AI agent failures: capture errors, diagnose patterns like loops or context overflow, apply contained recoveries, and generate introspection reports.
Compares coding agents like Claude Code and Aider on custom YAML-defined codebase tasks using git worktrees, measuring pass rate, cost, time, and consistency.
Unified inbox processor - handles ALL content dumped into inbox with parallel subagents and single-table review.
Key design: Subagents persist proposals immediately via TaskUpdate. If session crashes at item 23 of 50, items 1-22 are saved and resumable.
Single-session workflow. Creates quick resource/meeting notes with distilled: false. Use /para-obsidian:distill-resource for progressive summarization.
This orchestrator spawns triage-worker agents, each self-contained with preloaded skills:
┌─────────────────────────────────────────────────────────────┐
│ Tier 1: REFERENCE SKILLS (Knowledge) │
│ - para-classifier (PARA philosophy, emoji mapping) │
│ - content-processing (note creation, Layer 1, commit) │
│ - content-sourcing (URL routing, tool selection) │
└─────────────────────────────────────────────────────────────┘
↓ loaded by
┌─────────────────────────────────────────────────────────────┐
│ Tier 2: WORKER SKILLS (preloaded into triage-worker agent) │
│ - analyze-web (analyze web content → proposal) │
│ - analyze-voice (analyze transcription → proposal) │
│ - analyze-attachment (analyze PDF/DOCX → proposal) │
└─────────────────────────────────────────────────────────────┘
↓ orchestrated by
┌─────────────────────────────────────────────────────────────┐
│ Tier 3: ORCHESTRATOR (This skill) │
│ - triage (unified inbox processing) │
└─────────────────────────────────────────────────────────────┘
Note: content-processing is the canonical pipeline for note creation, Layer 1 injection, and commit — shared by triage-worker and quick-create. create-resource and create-meeting are standalone skills for non-triage workflows.
Phase 1: Initialize (coordinator)
├── Scan inbox, detect VTT files, create tasks
└── Load vault context (areas, projects)
Phase 2: Enrich + Analyze + Create (subagents)
├── Route to correct analyzer based on item type
├── Parallel for YouTube, articles, X/Twitter (batches of 10)
├── Sequential for Confluence only (single browser)
├── CREATE notes AND inject Layer 1 content (but DO NOT delete originals)
└── Enriched content stays in subagent context
Phase 2.5: Coordinator Verification (coordinator) ← AUTOMATIC
├── Runs automatically after ALL Phase 2 subagents complete, before Phase 3
├── For each proposal with created != null
├── para_fm_set: stamp summary + source + classification fields from proposal
├── para_fm_get: verify all critical fields populated
└── Override haiku's verification_status with coordinator's assessment
Phase 3: Present & Collaborate (coordinator) ← USER CHECKPOINT
├── Render table with all proposals
├── **ASK USER** - accept/edit/delete?
└── User reviews and can modify area/project/title
Phase 4: Edit (only if requested)
└── Apply edits via para_fm_set or re-create
Phase 5: Execute (coordinator) ← AFTER APPROVAL
├── Delete/archive originals (only now!)
├── Apply any remaining edits
└── Cleanup tasks + report
Key insight: Subagents create notes but originals stay until user approves. This enables collaborative review while keeping content isolated.
See: architecture.md for diagrams.
The orchestrator MUST NOT read content. All content reading happens in subagents. Never call para_read from the coordinator — spawn a subagent instead.
Why this is a hard rule: 50 inbox items × 10k average tokens = 500k tokens. This overflows the coordinator's context and causes timeouts. With isolation, the coordinator handles only ~500 bytes per item (proposals), keeping total context under 25k tokens.
See context-isolation.md for rules, token math, and common mistakes.
Check $ARGUMENTS:
| Input | Action |
|---|---|
Empty or all | Full inbox processing |
clippings / voice / attachments | Filter by type |
"filename.md" | Single file mode (skip batching) |
"filename.vtt" | Convert VTT first, then process |
Voice memo sync runs automatically via dynamic context injection before the skill reaches the agent. This ensures freshly recorded memos are in the inbox before Phase 1 scans it.
Result: !cd ${CLAUDE_PLUGIN_ROOT} && bun src/cli.ts voice 2>&1 | tail -5
If the output shows failures (e.g., parakeet-mlx not installed), log a warning and continue — existing transcriptions in the inbox will still be processed.
const tasks = TaskList();
const triageTasks = tasks.filter(t => t.subject.startsWith("Triage:"));
const analyzed = triageTasks.filter(t => t.status === "in_progress"); // proposals saved
const pending = triageTasks.filter(t => t.status === "pending"); // need processing
const completed = triageTasks.filter(t => t.status === "completed"); // already done
If existing triage tasks found:
Found existing triage session:
• 32 analyzed (proposals saved, notes created)
• 18 pending (need enrichment + analysis)
• 0 completed
Resume from where you left off? (y/n)
If yes:
pending tasks (spawn subagents for unprocessed items)created != null (idempotent)If no → delete existing triage tasks and start fresh (Phase 1).
Spawn a haiku preflight subagent to gather vault context cheaply:
Task({
model: "haiku",
subagent_type: "general-purpose",
description: "Triage preflight",
prompt: "<preflight prompt with mode=triage>"
})
Use the prompt template from ../brain/references/preflight-prompt.md with $MODE = triage.
Parse PREFLIGHT_JSON:{...} from the response. Extract areas, projects, inbox_items, and stakeholders.
Fallback: If the subagent fails, fall back to direct MCP calls:
para_list_areas({ response_format: "json" })
para_list_projects({ response_format: "json" })
para_config({ response_format: "json" })
Extract stakeholders array from config (names, roles, companies for transcription speaker matching).
If config.stakeholders is empty AND inbox contains voice memos/transcriptions, offer to add stakeholders. Stakeholders enable speaker matching in voice memo analysis — without them, all speakers appear as "Speaker 1", "Speaker 2", and project inference is disabled.
Trigger condition: Empty stakeholders + transcriptions in inbox. Skip if: No voice memos in inbox (stakeholders only help with transcription processing). Impact of skipping: Voice memo classification still works, but accuracy is reduced for multi-speaker scenarios and project inference is unavailable.
See stakeholder-bootstrap.md for the interactive wizard flow (bulk paste, one-at-a-time, or skip).
para_list({ path: "00 Inbox", response_format: "json" })
For each item, extract metadata only (no content):
para_fm_get({ file: itemPath, response_format: "json" })
Extract from frontmatter:
type → routes to analyzer skillsource → URL for enrichment (if clipping)areas, projects → pre-filled valuesDO NOT call para_read. Content analysis happens in Phase 2 subagents.
CRITICAL: VTT files must be converted to transcriptions before processing.
For each .vtt file found:
cd ${CLAUDE_PLUGIN_ROOT} && bun src/cli.ts voice convert "<vtt-path>" --format json
Date handling for VTT:
--date flag provided in $ARGUMENTS, use itvttDate for Phase 2 subagent referenceItem Type (routes to analyzer skill):
| Type | Detection | Analyzer Skill |
|---|---|---|
clipping | type === "clipping" | analyze-web |
transcription | type === "transcription" | analyze-voice |
attachment | PDF/DOCX extension | analyze-attachment |
vtt | .vtt extension | Convert first → analyze-voice |
Source Type (for enrichment within analyzer):
See enrichment-strategies.md for the canonical routing table (source detection, tool selection, parallelization constraints).
CRITICAL - X/Twitter: Web Clipper captures only stubs. You MUST enrich via X-API MCP tools (x_get_tweet) regardless of clipping content.
// For each inbox item:
TaskCreate({
subject: "Triage: ✂️ Article Name",
description: "File: 00 Inbox/✂️ Article.md\nType: clipping\nSource: youtube",
activeForm: "Analyzing article",
metadata: {
file: "00 Inbox/✂️ Article.md",
itemType: "clipping",
sourceType: "youtube",
proposal: null // Filled by subagent
}
})
Task IDs are auto-generated. Store mapping: { taskId → file }.
Call para_template_fields once per unique template type (usually just "resource", sometimes "meeting"). Pass results to subagents so they skip this call.
// For each unique proposed template:
para_template_fields({ template: "resource", response_format: "json" })
// → { validArgs, creation_meta: { contentTargets, dest, titlePrefix, sections } }
Store the results keyed by template name. Include in every subagent prompt (see subagent-prompts.md).
Found 50 items in inbox:
📋 By Type:
• 40 clippings
• 8 voice memos (including 2 converted VTT)
• 2 attachments
📋 By Enrichment:
• 35 parallel (YouTube, articles)
• 5 X/Twitter (parallel via X-API)
• 10 no enrichment needed
Starting subagent processing...
Key insight: Each subagent handles enrichment, analysis, AND note creation. Content stays isolated in subagent context - only lightweight proposals flow back to coordinator.
CRITICAL: Subagents create notes but DO NOT delete/archive originals. Deletion happens in Phase 5 AFTER user review and approval.
For all items (up to 10 per batch), spawn subagents in a single message for parallel execution. For inboxes >10 items, use batches of 10. Claude Code handles 7-10 parallel Task calls well for haiku subagents.
EXCEPTION: Confluence items must be sequential (single Chrome browser). Process these separately after parallel items complete.
Use the prompt template from subagent-prompts.md.
Pass these variables to each subagent:
taskId, file, sourceUrl, itemType, sourceTypeareas, projects, stakeholders (from Phase 1)templateFields (from Phase 1.6 — pre-loaded template metadata)MANDATORY batch mode flags: Instruct subagents to pass no_autocommit: true and skip_guard: true to para_create. These flags are required for parallel execution — without them, parallel subagents trigger git guard conflicts and unintended per-item commits. The coordinator bulk-commits once after all subagents complete (Phase 5).
Each subagent will: enrich content, analyze, create note (no commit), persist via TaskUpdate, and return PROPOSAL_JSON:{...}.
Override the agent's default model based on content complexity:
| Item Type | Model | Why |
|---|---|---|
clipping | haiku (default) | Enrichment provides strong structured source content (articles, videos, threads). Haiku handles well. |
transcription | sonnet | Transcriptions have ambiguous speakers, unclear meeting boundaries, and nuanced categorization (is this a standup or a 1on1?). Sonnet's reasoning handles this ambiguity better. |
vtt (converted) | sonnet | Same as transcription — multi-speaker meetings need stronger judgment |
attachment | haiku (default) | Document structure is usually clear (invoices, contracts have obvious patterns) |
// Pass model override in Task call:
Task({
subagent_type: "para-obsidian:triage-worker",
model: itemType === "transcription" ? "sonnet" : undefined, // undefined = use agent default (haiku)
description: "Process: ...",
prompt: `...`
})
Confluence requires Chrome DevTools (single browser instance). Process sequentially AFTER parallel items:
// After all parallel subagents complete, process Confluence items one at a time
for (const confluenceItem of confluenceItems) {
Task({
subagent_type: "triage-worker",
description: "Process: Confluence Page",
prompt: `... same prompt with sourceType: "confluence" ...`
})
// Wait for completion before next
}
Note: X/Twitter items are now processed in the parallel batch (Section 2.1) using stateless X-API MCP tools.
Proposal collection happens in Phase 3. Subagents return PROPOSAL_JSON:{...} in response text.
Subagents may fail during enrichment (timeouts, 404s, rate limits) or return invalid proposals.
Key behaviors:
pending (no TaskUpdate called)enrichmentFailed: true in metadataSee architecture.md#error-handling for detailed error flows and recovery patterns.
Rationale: Haiku triage-workers generate correct values in PROPOSAL_JSON but drop fields ~50% of the time when constructing para_create args. Haiku also falsely reports verification_status: "verified" when fields are empty. The coordinator has authoritative values from PROPOSAL_JSON and stamps them unconditionally — idempotent (if haiku got it right, overwriting with the same value does no harm).
This replaces trust in haiku's verification_status. Workers now set verification_status: "pending_coordinator" and skip post-creation verification.
| Template | Fields Stamped | Source |
|---|---|---|
resource | summary, source, source_format, resource_type, areas, projects | proposal + task metadata (sourceUrl) |
meeting | summary, area, meeting_type | proposal |
invoice/booking | (skip) | N/A |
For each proposal where created != null and template not in [invoice, booking]:
sourceUrl for source field)para_fm_set with skip_guard: true — stamp all critical fields unconditionally (no git guard conflicts during batch)fm_set response — use result.attributes.after to check fields (no separate para_fm_get needed)"verified", if any still empty → "needs_review"verification_status with the coordinator's assessmentpara_commit() to commit all stamped changesSee execution-phases.md for full pseudocode and field mapping.
Key insight: This is the collaborative checkpoint. Notes are already created, but originals still exist. User reviews proposals and can edit before we clean up.
Collect proposals from subagent response text (normal flow) or TaskGet loop (resume flow). Render table with all proposals. Ask user to Accept/Edit/Delete/Quit. Never skip the collaborative checkpoint.
See execution-phases.md for proposal collection code, table format, and checkpoint details.
Quick inline edits for area, project, title, or type. Show current values, prompt for changes, update task metadata.
See execution-phases.md for edit flow.
Notes are ALREADY created by subagents (uncommitted in batch mode). Phase 5 handles:
para_commit() once to commit all notes created by subagents (batch mode)created and layer1_injected fieldspara_fm_set if area/project changeditemType (see table below)Route on itemType (source content), NOT proposed_template (output type). A transcription classified as a resource is STILL archived, never deleted.
| itemType | Action | Why |
|---|---|---|
transcription | Archive via para_rename to 04 Archives/Transcriptions/, then update resource note source to [[archived note]] via para_fm_set | Raw recordings have intrinsic value - NEVER delete. Resource note must link back to archived transcription |
clipping | Delete via para_delete | Content captured in resource note |
attachment | Delete inbox note via para_delete | PDF/DOCX stays in Attachments/ |
clipping (non-URL) | Keep in inbox | Thought/conversation clippings are manual review items. Detection: sourceUrl is empty or doesn't start with http |
NEVER use para_delete on transcriptions. Always use para_rename to archive them.
See execution-phases.md for status matrix, code patterns, and report format.
| State | Meaning | What exists |
|---|---|---|
pending | Created by coordinator in Phase 1, NOT yet processed by subagent | Original inbox file only |
in_progress | Subagent completed: note created, proposal saved in metadata | New note + original inbox file (both exist) |
completed | User approved in Phase 3, original deleted/archived in Phase 5 | New note only (original cleaned up) |
State flow: pending → (subagent enriches + analyzes + creates note + calls TaskUpdate) → in_progress → (user approves + coordinator cleans up) → completed
If session crashes/quits:
status: "in_progress" have notes created + proposals saved in metadata + originals preservedstatus: "pending" need full processing (subagent never ran or crashed before TaskUpdate)/triage again → Phase 0 detects existing tasks → offers resumepending tasks (re-spawn subagents)created != null (idempotent — safe to re-stamp)For classification decision trees and emoji mappings used during analysis, see the para-classifier skill:
These provide the framework for determining note types and source_format values.
The triage-worker agent has these skills preloaded:
| Skill | Purpose | When Used |
|---|---|---|
| analyze-web | Analyze web clippings | itemType === "clipping" |
| analyze-voice | Analyze transcriptions | itemType === "transcription" |
| analyze-attachment | Analyze PDF/DOCX | itemType === "attachment" |
Standalone skills (not used during triage — the worker handles creation inline):
| Skill | Purpose | When Used |
|---|---|---|
| create-resource | Create resource note | Non-triage workflows |
| create-meeting | Create meeting note | Non-triage workflows |
After the final report in Phase 5, emit a structured completion signal so the brain orchestrator can parse the outcome:
SKILL_RESULT:{"status":"ok","skill":"triage","summary":"Processed N items","processed":N}SKILL_RESULT:{"status":"partial","skill":"triage","processed":N,"failed":M}SKILL_RESULT:{"status":"ok","skill":"triage","summary":"Inbox is empty"}SKILL_RESULT:{"status":"ok","skill":"triage","summary":"Cancelled by user"}| File | Content |
|---|---|
| proposal-schema.md | Canonical proposal structure, field names, confidence levels, TaskUpdate format |
| architecture.md | Flow diagrams, design rationale |
| context-isolation.md | Context isolation rules, common mistakes |
| enrichment-strategies.md | Tool selection by source, voice memo cases, constraints |
| execution-phases.md | Phases 2.5-5 detailed implementation |
| subagent-prompts.md | Analysis prompt templates |
| output-templates.md | Table format, actions |
| task-patterns.md | TaskCreate/Update API usage |
| stakeholder-bootstrap.md | Interactive stakeholder wizard |