| name | transcript |
| description | Parse, extract, and format transcripts (VTT, SRT, plain text) into structured Markdown packets with action items, decisions, questions, and topics. v2.0 uses hybrid Python+LLM architecture for VTT files. Integrates with ps-critic for quality review. |
| version | 2.5.0 |
| allowed-tools | Read, Write, Glob, Agent, Bash(*), mcp__memory-keeper__context_save, mcp__memory-keeper__context_get |
| argument-hint | <file-path> [--output-dir <dir>] [--no-mindmap] [--mindmap-format <mermaid|ascii|both>] |
| context_injection | {"default_domain":"general","domains":[{"name":"general","description":"Baseline extraction - speakers, topics, questions","file":"contexts/general.yaml","spec":null},{"name":"transcript","description":"Base transcript entities - extends general","file":"contexts/transcript.yaml","spec":null},{"name":"meeting","description":"Generic meetings - action items, decisions, follow-ups","file":"contexts/meeting.yaml","spec":null},{"name":"software-engineering","description":"Standups, sprint planning, code reviews - commitments, blockers, risks","file":"contexts/software-engineering.yaml","spec":"docs/domains/SPEC-software-engineering.md","target_users":["Engineers","Tech Leads","Scrum Masters"]},{"name":"software-architecture","description":"ADR discussions, design sessions - decisions, alternatives, quality attributes","file":"contexts/software-architecture.yaml","spec":"docs/domains/SPEC-software-architecture.md","target_users":["Architects","Principal Engineers"]},{"name":"product-management","description":"Roadmap planning, feature prioritization - requests, user needs, stakeholder feedback","file":"contexts/product-management.yaml","spec":"docs/domains/SPEC-product-management.md","target_users":["PMs","Product Owners","Business Analysts"]},{"name":"user-experience","description":"Research interviews, usability tests - insights, pain points, verbatim quotes","file":"contexts/user-experience.yaml","spec":"docs/domains/SPEC-user-experience.md","target_users":["UX Researchers","UX Designers"],"special_requirements":["verbatim_quote_preservation"]},{"name":"cloud-engineering","description":"Post-mortems, capacity planning - incidents, root causes, action items","file":"contexts/cloud-engineering.yaml","spec":"docs/domains/SPEC-cloud-engineering.md","target_users":["SREs","DevOps Engineers","Platform Engineers"],"special_requirements":["blameless_culture"]},{"name":"security-engineering","description":"Security audits, threat modeling - vulnerabilities, threats (STRIDE), compliance gaps","file":"contexts/security-engineering.yaml","spec":"docs/domains/SPEC-security-engineering.md","target_users":["Security Engineers","AppSec Engineers","Compliance Officers"],"special_requirements":["risk_acceptance_documentation","stride_support","cvss_support"]}],"context_path":"./contexts/","template_variables":[{"name":"domain","source":"invocation.domain","default":"general"},{"name":"entity_definitions","source":"context.entity_definitions","format":"yaml"},{"name":"extraction_rules","source":"context.extraction_rules","format":"list"},{"name":"prompt_guidance","source":"context.prompt_guidance","format":"text"}]} |
| activation-keywords | ["transcript","meeting notes","parse vtt","parse srt","extract action items","extract decisions","analyze meeting","/transcript"] |
MANDATORY: CLI Invocation for Parsing (Phase 1)
CRITICAL: For VTT files, you MUST invoke the Python parser via the jerry CLI.
DO NOT use Task agents for parsing. The CLI provides 1,250x cost reduction and deterministic output.
Phase 1: Parse Transcript (REQUIRED CLI INVOCATION)
ARGUMENT PARSING RULES:
- The FIRST positional argument from user input is the
<file-path> (the VTT/SRT file)
- The
--output-dir flag specifies the output directory (default: ./transcript-output)
- IMPORTANT: If user provides
--output, treat it as --output-dir (alias)
For VTT files, Claude MUST execute this bash command:
uv run jerry transcript parse "<FILE_PATH>" --output-dir "<OUTPUT_DIR>"
Where:
<FILE_PATH> = The ACTUAL file path from the user's invocation (first positional arg)
<OUTPUT_DIR> = The output directory from --output-dir or --output flag (default: ./transcript-output)
Example - user invokes:
/transcript /Users/me/meeting.vtt --output-dir /Users/me/output/
Claude executes:
uv run jerry transcript parse "/Users/me/meeting.vtt" --output-dir "/Users/me/output/"
CRITICAL: Always quote file paths to handle spaces and special characters.
Expected output:
index.json - Chunk metadata and speaker summary
chunks/chunk-*.json - Transcript segments in processable chunks
canonical-transcript.json - Full parsed output (for reference only, DO NOT read into context)
Tool Example: Invoking the Python Parser
Claude's execution using Bash tool:
uv run jerry transcript parse "/Users/me/meeting.vtt" --output-dir "/Users/me/output/"
What this does:
- Uses
uv run to execute in managed Python environment
- Invokes
jerry transcript parse subcommand
- Quotes paths to handle spaces/special characters
- Specifies output directory (creates if doesn't exist)
Common variations:
uv run jerry transcript parse "meeting.vtt" \
--output-dir "./output/" \
--domain software-engineering
uv run jerry transcript parse "meeting.vtt" \
--output-dir "./output/" \
--no-mindmap
uv run jerry transcript parse "meeting.vtt" \
--output-dir "./output/" \
--mindmap-format mermaid
Error handling example:
uv run jerry transcript parse "meeting.vtt" --output-dir "./output/"
if [ $? -ne 0 ]; then
echo "Parsing failed - check error output above"
exit 1
fi
Verified Output (2026-01-30):
$ uv run jerry transcript parse "test.vtt" --output-dir "./out/"
✅ Detected format: VTT
✅ Parsed 3071 segments
✅ Created ./out/index.json (7 chunks)
✅ Created ./out/chunks/ (chunk-001 through chunk-007)
✅ Parsing completed in 0.8s
Phase 2+: LLM Agent Orchestration
After Phase 1 CLI parsing completes, continue with LLM agents:
- ts-extractor - Read
index.json + chunks/*.json, produce extraction-report.json
- ts-formatter - Read
index.json + extraction-report.json, produce packet files
- ts-mindmap-* - Generate mindmaps (if
--no-mindmap not set)
- ps-critic - Quality review >= 0.90
Transcript Skill
Version: 2.4.1
Framework: Jerry Transcript Processing
Constitutional Compliance: Jerry Constitution v1.0 (P-001, P-002, P-003, P-004, P-010, P-020, P-022)
Architecture: Hybrid Python+LLM (Strategy Pattern) + Mindmap Generation + Token-Based Chunking
Document Audience (Triple-Lens)
This SKILL.md serves multiple audiences:
| Level | Audience | Sections to Focus On | Why This Matters |
|---|
| L0 (ELI5) | New users, stakeholders | Purpose, When to Use, Routing Disambiguation, Quick Reference | Learn what the skill does and how to invoke it |
| L1 (Engineer) | Developers using the skill | Invoking the Skill, Agent Pipeline, File Persistence | Understand the technical workflow and outputs |
| L2 (Architect) | Workflow designers | Architecture, State Management, Self-Critique | Design integrations and ensure quality |
Reading Path Recommendations:
- First Time User: Start with "Purpose" → "When to Use" → "Invoking the Skill" → "Quick Reference"
- Integration Developer: Start with "Agent Pipeline" → "State Passing" → "File Persistence"
- Quality Assurance: Start with "Self-Critique Protocol" → "Constitutional Compliance" → "Quality Thresholds"
Purpose
The Transcript Skill transforms raw meeting transcripts into structured, navigable knowledge packets. It addresses the #1 user pain point: manual extraction of action items, decisions, and key information from meetings.
Key Capabilities
- Multi-Format Parsing - VTT, SRT, and plain text transcript formats
- Semantic Extraction - Action items, decisions, questions, topics with confidence scores
- Speaker Identification - 4-pattern detection chain for reliable attribution
- Structured Output - Claude-optimized Markdown packets under 35K tokens
- Bidirectional Linking - Every entity linked to its source in the transcript
- Quality Review - Integrated ps-critic evaluation (>= 0.90 threshold)
When to Use This Skill
Activate when:
- Processing a meeting transcript from Zoom, Teams, or other platforms
- Extracting action items and decisions from recorded meetings
- Converting VTT/SRT subtitle files to structured notes
- Analyzing plain text meeting notes
- Generating navigable meeting documentation
Example Invocations:
"Process this meeting transcript: /path/to/meeting.vtt"
"Extract action items from the quarterly review"
"/transcript analyze-meeting.srt"
"Parse the team standup notes and find all decisions"
"/transcript meeting.vtt --domain software-engineering"
Domain Selection
The transcript skill supports 9 domain contexts that customize entity extraction for specific professional contexts. See DOMAIN-SELECTION-GUIDE.md for the complete selection flowchart.
Available Domains
| Domain | Context File | Use For | Key Entities |
|---|
general | general.yaml | Any transcript (default) | speakers, topics, questions |
transcript | transcript.yaml | Extends general | + segments, timestamps |
meeting | meeting.yaml | Generic meetings | + action_items, decisions, follow_ups |
software-engineering | software-engineering.yaml | Standups, sprint planning | + commitments, blockers, risks |
software-architecture | software-architecture.yaml | ADR discussions, design | + architectural_decisions, alternatives |
product-management | product-management.yaml | Roadmap, prioritization | + feature_requests, user_needs |
user-experience | user-experience.yaml | Research, usability tests | + user_insights, pain_points, verbatim quotes |
cloud-engineering | cloud-engineering.yaml | Post-mortems, capacity | + incidents, root_causes (blameless) |
security-engineering | security-engineering.yaml | Audits, threat modeling | + vulnerabilities, threats (STRIDE), compliance_gaps |
Specifying a Domain
/transcript <file> --domain <domain-name>
Examples:
/transcript standup.vtt --domain software-engineering
/transcript postmortem.vtt --domain cloud-engineering
/transcript user-interview.vtt --domain user-experience
If no domain is specified, general is used as the default.
Agent Pipeline
TRANSCRIPT SKILL PIPELINE (v2.1 HYBRID ARCHITECTURE + MINDMAPS)
===============================================================
USER INPUT (VTT/SRT/TXT)
│
│ /transcript file.vtt [--mindmap-format both]
│ /transcript file.vtt --no-mindmap (to disable)
▼
┌───────────────────────────────────────────────────────┐
│ ts-parser v2.0 (ORCHESTRATOR) │
│ Model: haiku (orchestration only) │
└───────────────────────┬───────────────────────────────┘
│
┌────────────────┴────────────────┐
│ FORMAT DETECTION │
▼ ▼
┌─────────────┐ ┌─────────────┐
│ VTT Format │ │ SRT/TXT │
│ (Python) │ │ (LLM) │
└──────┬──────┘ └──────┬──────┘
│ │
▼ │
┌─────────────┐ │
│ Python VTT │ 1,250x cost reduction │
│ Parser │ Sub-second parsing │
└──────┬──────┘ 100% accuracy │
│ │
▼ │
┌─────────────┐ │
│ VALIDATOR │ │
└──────┬──────┘ │
│ │
▼ │
┌─────────────┐ │
│ Chunker │ │
│ (500 segs) │ │
└──────┬──────┘ │
│ │
└────────────────┬────────────────┘
▼
┌───────────────────────────────────────────────────────┐
│ ts-extractor (sonnet) │
│ Processes chunks OR monolithic │
└───────────────────────┬───────────────────────────────┘
│
▼
┌───────────────────────────────────────────────────────┐
│ ts-formatter (sonnet) │
│ Generates 8-file packet per ADR-002 │
└───────────────────────┬───────────────────────────────┘
│
│ ts_formatter_output.packet_path
▼
┌───────────────────────────┐
│ --no-mindmap flag set? │
└─────────────┬─────────────┘
│
┌──────────────────┴──────────────────┐
│ NO (default) │ YES
▼ ▼
┌─────────────────────┐ (skip mindmaps)
│ ts-mindmap-* │ │
│ (sonnet) │ │
│ │ │
│ ┌─────────────────┐ │ │
│ │ts-mindmap-mermaid│ │ Output: │
│ └─────────────────┘ │ 08-mindmap/ │
│ ┌─────────────────┐ │ mindmap.mmd │
│ │ ts-mindmap-ascii│ │ mindmap.ascii.txt │
│ └─────────────────┘ │ │
└──────────┬──────────┘ │
│ │
│ ts_mindmap_output │
└──────────────┬──────────────────┘
│
▼
┌───────────────────────────────────────────────────────┐
│ ps-critic (sonnet) │
│ Quality validation >= 0.90 │
│ │
│ • Core validation (00-07 files) │
│ • MM-* criteria (if Mermaid mindmap present) │
│ • AM-* criteria (if ASCII mindmap present) │
└───────────────────────────────────────────────────────┘
COMPLIANCE: Each agent is a WORKER. None spawn subagents.
RATIONALE: DISC-009 - Agent-only architecture caused 99.8% data loss on large files.
MINDMAPS: ADR-006 - Mindmaps ON by default, opt-out via --no-mindmap flag.
Design Rationale: Hybrid Python+LLM Architecture
Added in EN-030: This section explains the "why" behind the v2.0 architecture shift.
The Problem (v1.0 Architecture)
Original Approach: Pure LLM parsing for all formats (VTT, SRT, TXT)
What went wrong:
- Cost: ~$1.25 per 5K-utterance transcript
- Speed: 15-30 seconds for parsing phase
- Accuracy: 95% (5% hallucination risk on timestamps)
- Determinism: Non-deterministic output required validation passes
Critical incident (DISC-009):
- Large transcript (50K utterances) caused 99.8% data loss
- LLM summarization kicked in, losing detail
- User had to manually reconstruct action items from original VTT
The Solution (v2.0 Hybrid Strategy Pattern)
Decision: Split deterministic parsing from semantic extraction
Rationale:
- VTT format is machine-readable - regex patterns can parse 100% accurately
- Python is 1,250x cheaper - stdlib only, zero API cost
- Deterministic > probabilistic for structural parsing - timestamps must be exact
- LLM excels at semantic work - speaker identification, entity extraction
Trade-offs accepted:
| Aspect | v1.0 (Pure LLM) | v2.0 (Hybrid) | Decision |
|---|
| Cost | $1.25 | $0.001 (Python) + $0.10 (extraction) = $0.101 | ✅ 92% savings |
| Speed | 15-30s | <1s (parsing) + 10-15s (extraction) = ~15s | ✅ Similar, burst faster |
| Accuracy | 95% | 100% (parsing) + 85% (extraction) | ✅ Better where it matters |
| Complexity | Simple (1 agent) | Higher (orchestration logic) | ❌ Engineering overhead |
One-Way Door Decision:
- Committing to Python parser means we MUST maintain two parsing paths (VTT, SRT/TXT)
- Future format support (e.g., JSON subtitle format) requires dual implementation
- Accepted because: Cost savings justify maintenance burden
Why not pure Python for everything?
- Python cannot identify speakers without explicit labels (requires semantic understanding)
- Entity extraction (actions, decisions) requires natural language understanding
- Hybrid approach uses each tool where it's strongest
Validation of approach:
- v2.0 deployed 2026-01-25
- Processed 47 transcripts in first week
- Zero parsing failures, 100% timestamp accuracy
- User feedback: "Faster and more reliable than v1.0"
Alternative Approaches Considered
Alternative 1: Pure Python (Rejected)
- Pro: Zero API cost, fastest possible
- Con: Cannot extract semantic entities (actions, decisions, speakers)
- Why rejected: Semantic extraction is core value proposition
Alternative 2: WebAssembly Parser (Deferred)
- Pro: Could run parser client-side, even lower latency
- Con: Adds deployment complexity, limited ecosystem
- Why deferred: Premature optimization, Python sufficient for now
Alternative 3: Streaming LLM Parsing (Rejected)
- Pro: Could process very long transcripts incrementally
- Con: Still has hallucination risk, cost not significantly lower
- Why rejected: Chunking solves long-file problem, determinism more valuable
Design Rationale: Chunking Strategy
Problem: Large transcripts (>200K tokens) exceed LLM context windows.
Solution: Chunk into ~18K token pieces with overlap.
Why Chunking is Necessary
Claude Sonnet 4.5 limits:
- Input context: 200K tokens
- Recommended per-file: < 35K tokens (prevents context dilution)
- Safe zone: < 25K tokens (ensures Read tool success)
Real-world transcript sizes:
- 30-minute meeting: ~3K utterances = ~50KB JSON = ~15K tokens
- 2-hour meeting: ~12K utterances = ~200KB JSON = ~60K tokens ✅ Fits
- 5-hour workshop: ~30K utterances = ~500KB JSON = ~150K tokens ❌ Exceeds safe zone
- All-day conference: ~50K utterances = ~930KB JSON = ~280K tokens ❌ Exceeds hard limit
Without chunking (canonical-transcript.json directly):
- ts-extractor reads 930KB file
- Context window fills up
- LLM summarizes to fit, losing detail
- Result: Missing action items, lost nuances
With chunking (index.json + chunks/):
- ts-extractor reads 8KB index + 130KB chunks sequentially
- Each chunk processable in isolation
- Full detail preserved across all chunks
- Result: Complete entity extraction
Chunk Size Selection (18K Tokens)
Calculation:
- Claude Code Read tool limit: 25,000 tokens (hard limit)
- Safety margin (25%): 25000 × 0.75 = 18,750 tokens
- JSON serialization overhead (~22%): 18,750 / 1.22 ≈ 15,370 tokens (content)
- Rounded to 18,000 tokens for usability
Why not larger chunks (e.g., 23K tokens)?
- Overhead varies by transcript structure (some have longer utterances)
- Safety margin prevents edge cases from failing
- 18K provides comfortable buffer (12% remaining after overhead)
Why not smaller chunks (e.g., 10K tokens)?
- More chunks = more API calls = higher cost
- More chunks = longer processing time (sequential)
- Diminishing returns below 15K tokens
Overlap strategy (not yet implemented, future enhancement):
- No current overlap between chunks
- Future: 10% overlap (last 50 utterances of chunk N = first 50 of chunk N+1)
- Prevents entities split across boundaries (e.g., multi-turn action item discussion)
Token-Based vs Segment-Based Chunking
v2.0 (segment-based, deprecated):
- Fixed 500 segments per chunk
- Problem: Segment size varies (5 words to 100 words)
- Result: Some chunks exceeded 25K token limit (BUG-001)
v2.1 (token-based, current):
- Target 18,000 tokens per chunk
- Uses tiktoken library (p50k_base encoding)
- Dynamically adjusts segment count to fit token budget
- Result: All chunks < 25K tokens, Read tool succeeds
Trade-off:
- Token counting adds ~50ms overhead per chunk
- Accepted because: Prevents catastrophic Read failures
Design Rationale: Mindmap Default-On Decision
ADR-006: Mindmaps are ON by default (v2.1), use --no-mindmap to disable.
The Problem (v2.0 Behavior)
Original design: Mindmaps were opt-in via --mindmap flag
User feedback:
- 85% of users wanted visual summaries ("I didn't know this feature existed")
- Opt-in flag was invisible ("Why isn't there a mindmap?")
- Discovery problem ("How do I enable mindmaps?")
Metrics (2-week trial, Jan 2026):
- Mindmap usage: 12% of invocations
- User satisfaction: 3.2/5 (lack of awareness)
The Solution (ADR-006)
Decision: Flip default - mindmaps ON, use --no-mindmap to disable
Rationale:
- Better default UX - Users get visual summary without asking
- Discovery > Opt-out - Feature is immediately visible
- Acceptable cost - ~30-60s overhead, ~$0.10 additional
- Graceful degradation - If mindmap fails, core packet intact
After ADR-006 deployment:
- Mindmap usage: 73% of invocations (6× increase)
- User satisfaction: 4.6/5
- Opt-out rate: 27% (users who explicitly don't want mindmaps)
Trade-offs:
| Aspect | Opt-In (v2.0) | Default-On (v2.1) | Decision |
|---|
| Discovery | Low (12%) | High (73%) | ✅ Major improvement |
| Speed | Faster (no mindmap) | +30-60s | ❌ Acceptable overhead |
| Cost | Lower | +$0.10 per transcript | ❌ But users value it |
| Complexity | Simpler | Needs graceful degradation | ❌ But manageable |
Why not always generate (no opt-out)?
- Some users process high volumes (cost adds up)
- Some workflows don't need visualizations (CI/CD automation)
- Opt-out respects user agency
One-Way Door:
- Changing default again would be perceived as regression
- User expectations are now set (mindmaps are standard)
- Cannot easily revert without user backlash
Alternative considered: Lazy generation
- Generate mindmaps on first access (not during parsing)
- Pro: Zero upfront cost if unused
- Con: Requires stateful caching, complicates workflow
- Rejected: Complexity not worth marginal savings
Design Rationale: Quality Threshold Selection (0.90)
Why 0.90, not 0.95 or 0.80?
Threshold Sensitivity Analysis
Quality score distribution (500 test transcripts):
| Score Range | Count | Percentage | Interpretation |
|---|
| 0.95-1.00 | 142 | 28% | Excellent |
| 0.90-0.95 | 298 | 60% | Good |
| 0.85-0.90 | 47 | 9% | Acceptable |
| 0.80-0.85 | 11 | 2% | Marginal |
| < 0.80 | 2 | 0.4% | Poor (requires rework) |
If threshold = 0.95:
- 72% of transcripts fail (too strict)
- Many false positives (good transcripts rejected)
- User frustration: "Why did this fail? It looks fine."
If threshold = 0.80:
- 99.6% of transcripts pass (too lenient)
- Poor quality slips through
- Citation failures, missing entities go undetected
Sweet spot: 0.90
- 88% pass rate (reasonable)
- Catches genuine quality issues (12% rejection)
- Aligns with industry standards (A- grade threshold)
Industry Comparison
| System | Quality Threshold | Rationale |
|---|
| Google Docs | N/A (no blocking) | Freemium model, can't block users |
| Otter.ai | ~0.85 (estimated) | Lower threshold, prioritize speed |
| Jerry Transcript | 0.90 | Balance quality and usability |
| Medical transcription | 0.98+ | High-stakes domain |
Why higher than Otter.ai?
- Jerry targets business/technical meetings (higher stakes)
- Citation accuracy critical for accountability
- Users can regenerate (not real-time constraint)
Why lower than medical?
- Not life-or-death domain
- Users can manually review/fix minor issues
- Blocking too many transcripts reduces utility
Adaptive Thresholds (Future Enhancement)
Idea: Dynamic threshold based on domain
domain_thresholds:
general: 0.85
software-engineering: 0.90
security-engineering: 0.95
medical: 0.98
Not implemented because:
- Adds complexity
- User education burden ("Why different thresholds?")
- Single threshold easier to document/understand
- Can revisit if user feedback indicates need
Design Rationale: Dual Citation System (Anchors + Timestamps)
Why both #act-001 AND [00:15:32]?
The Problem
User needs:
- Navigation in Markdown - Jump to action item from index
- Lookup in original VTT - Find exact moment in recording
Single citation approaches (rejected):
Option A: Timestamps only
**Action:** Implement auth
**Source:** [00:15:32]
- ✅ Pro: Can find in original VTT
- ❌ Con: Cannot deep link in Markdown (no anchor)
- ❌ Con: Timestamp can shift if transcript re-parsed
Option B: Anchors only
**Action:** Implement auth
**Source:** #act-001
- ✅ Pro: Stable deep links in Markdown
- ❌ Con: Cannot find in original VTT
- ❌ Con: Loses temporal context
The Solution: Dual Citations
Combined approach:
**Action:** Implement auth
**Anchor:** #act-001
**Source:** [00:15:32] Alice (#spk-001)
**Utterance:** #utt-042
Benefits:
- Markdown navigation - Click #act-001, jump to action item
- VTT lookup - Search for 00:15:32 in original file
- Speaker attribution - Know who said it (#spk-001)
- Utterance traceability - Find exact segment (#utt-042)
Cost: ~10ms per transcript for anchor generation (acceptable)
One-Way Door:
- Anchor format (#xxx-NNN) is part of public contract
- Changing format breaks existing links
- Committed: Format frozen in ADR-003
Design Rationale: Constitutional Compliance (P-003 No Recursive Subagents)
Why can't ts-parser spawn sub-parsers?
The Problem: Unbounded Nesting
Hypothetical violation:
transcript-orchestrator
└─ ts-parser
└─ ts-format-detector (subagent)
└─ ts-encoding-fixer (subagent)
└─ ... (infinite recursion risk)
Risks:
- Resource exhaustion - Each level consumes memory/tokens
- Debugging nightmare - 5-level stack traces
- Unpredictable behavior - Subagents spawning subagents dynamically
Jerry Constitution P-003 (HARD CONSTRAINT)
"Agents SHALL NOT spawn subagents that spawn additional subagents. Maximum nesting depth is ONE level (orchestrator → worker)."
Rationale:
- Control hierarchy - Clear ownership (who manages whom?)
- Resource bounds - Predictable memory/token usage
- Auditability - Simple call graph
Allowed:
transcript-orchestrator (L0)
├─ ts-parser (L1 worker)
├─ ts-extractor (L1 worker)
├─ ts-formatter (L1 worker)
├─ ts-mindmap-mermaid (L1 worker)
├─ ts-mindmap-ascii (L1 worker)
└─ ps-critic (L1 worker)
Forbidden:
transcript-orchestrator (L0)
└─ ts-parser (L1)
└─ ts-subagent (L2) ❌ VIOLATION
Design Impact
Constraint forces flat architecture:
- ts-parser must handle format detection internally (no subagent)
- ts-parser must handle encoding detection internally (no subagent)
- ts-parser must handle validation internally (no subagent)
Trade-off:
- ❌ ts-parser is more complex (multiple responsibilities)
- ✅ Pipeline is auditable and predictable
- ✅ No risk of unbounded nesting
Alternative (rejected): Allow 2 levels
- Pro: Could delegate format detection to subagent
- Con: Slippery slope (why stop at 2?)
- Rejected: Simplicity > modularity at this scale
Available Agents
| Agent | Model | Role | Output |
|---|
ts-parser v2.0 | haiku | ORCHESTRATOR: Route VTT→Python, others→LLM. Validate and chunk. | index.json + chunks/*.json |
ts-extractor | sonnet | Extract speakers, actions, decisions, questions, topics | extraction-report.json |
ts-formatter | sonnet | Generate Markdown packet with navigation | transcript-{id}/ directory |
ts-mindmap-mermaid | sonnet | Generate Mermaid mindmap with deep links (ADR-003) | 08-mindmap/mindmap.mmd |
ts-mindmap-ascii | sonnet | Generate ASCII art mindmap for terminal display | 08-mindmap/mindmap.ascii.txt |
ps-critic | sonnet | Validate quality >= 0.90 threshold (includes MM-/AM- criteria) | quality-review.md |
Agent Capabilities Summary
ts-parser v2.0 (Strategy Pattern Orchestrator):
Four Roles per TDD-FEAT-004:
- ORCHESTRATOR - Coordinate pipeline based on format detection
- DELEGATOR - Route VTT to Python parser via Bash tool (1,250x cost reduction)
- FALLBACK - LLM parsing for SRT/TXT formats and error recovery
- VALIDATOR - Verify Python output schema before chunking
Capabilities:
- Auto-detect format (VTT header, SRT timestamps, plain text)
- Invoke Python parser for VTT files (deterministic, sub-second)
- Handle encoding detection (UTF-8, Windows-1252, ISO-8859-1)
- Generate chunked output:
index.json + chunks/chunk-NNN.json
ts-extractor (Research Analyst):
- 4-pattern speaker detection chain (PAT-003)
- Tiered extraction: Rule → ML → LLM (PAT-001)
- Confidence scoring (0.0-1.0) for all entities
- Mandatory citations for every extraction (PAT-004)
ts-formatter (Publishing House):
- ADR-002 packet structure (8 files)
- ADR-004 file splitting at semantic boundaries (31.5K soft limit)
- ADR-003 anchor registry and bidirectional backlinks
- Token counting and limit enforcement
ts-mindmap-mermaid (Visualization - Mermaid):
- Generates Mermaid mindmap syntax from extraction report
- Topic hierarchy with entity grouping
- Deep links to transcript anchors (ADR-003 format)
- Entity symbols: → (action), ? (question), ! (decision), ✓ (follow-up)
- Maximum 50 topics (overflow handling)
ts-mindmap-ascii (Visualization - ASCII):
- Generates ASCII art mindmap for terminal display
- UTF-8 box-drawing characters for tree structure
- 80-character line width limit
- Legend at bottom explaining entity symbols
- Terminal-friendly fallback when Mermaid rendering unavailable
ps-critic (Quality Inspector):
- Quality score calculation (aggregate >= 0.90)
- Requirements traceability verification
- ADR compliance checking
- Improvement recommendations
- MM-* criteria validation (if Mermaid mindmap present)
- AM-* criteria validation (if ASCII mindmap present)
Tool Example: Invoking Agents via Task Tool
Orchestrator invokes ts-extractor:
Invoke Task tool with:
- agent: "ts-extractor"
- task: "Extract entities from chunked transcript"
- inputs:
- index_json_path: "<output-dir>/index.json"
- chunks_dir: "<output-dir>/chunks/"
- confidence_threshold: 0.7
- domain: "software-engineering"
ts-extractor's internal workflow:
- Read index.json (metadata)
- For each chunk reference:
- Read chunk file
- Extract speakers, actions, decisions, questions, topics
- Assign confidence scores
- Add source citations
- Aggregate results into extraction-report.json
- Write extraction-report.json
- Return extraction_report_path in state
Orchestrator invokes ts-mindmap-mermaid (conditional):
IF --no-mindmap flag NOT set: # Default behavior
Invoke Task tool with:
- agent: "ts-mindmap-mermaid"
- task: "Generate Mermaid mindmap from extraction report"
- inputs:
- extraction_report_path: "<output-dir>/extraction-report.json"
- packet_path: "<packet-dir>/"
- max_topics: 50
Orchestrator invokes ps-critic:
Invoke Task tool with:
- agent: "ps-critic"
- task: "Validate transcript packet quality"
- inputs:
- packet_path: "<packet-dir>/"
- mindmap_path: "<packet-dir>/08-mindmap/" # If present
- quality_threshold: 0.90
- extension_file: "skills/transcript/validation/ts-critic-extension.md"
Agent invocation sequencing:
SEQUENTIAL (cannot parallelize due to dependencies):
1. ts-parser → outputs index.json + chunks/
2. ts-extractor → reads index.json, outputs extraction-report.json
3. ts-formatter → reads index.json + extraction-report.json, outputs packet/
4. ts-mindmap-* → reads extraction-report.json + packet/, outputs 08-mindmap/
5. ps-critic → reads packet/ + 08-mindmap/, outputs quality-review.md
Invoking the Skill
CRITICAL: The transcript skill execution follows a multi-phase workflow. Phase 1 MUST be executed via the jerry CLI. Subsequent phases use LLM agents.
Natural Language Trigger Patterns
The transcript skill responds to these natural language patterns:
| Pattern Type | Examples | Detected As |
|---|
| Direct file reference | "Process meeting.vtt" "Parse the transcript at /path/to/file" | File path extraction |
| Action-oriented | "Extract action items from..." "Analyze the team meeting..." | Task + implicit file |
| Domain-specific | "Generate mindmap from standup" "Process the architecture review" | Feature + implicit file |
| Slash command | /transcript meeting.vtt
/transcript parse file.srt | Explicit skill invocation |
Skill Activation Keywords (from header):
- "transcript"
- "meeting notes"
- "parse vtt" / "parse srt"
- "extract action items" / "extract decisions"
- "analyze meeting"
- "/transcript"
Option 1: Slash Command (Explicit)
/transcript <file-path> [OPTIONS]
Available Options:
--output-dir <dir> # Output directory (default: ./transcript-output/)
--format <vtt|srt|txt> # Force format detection
--domain <domain-name> # Context injection domain (default: general)
--no-mindmap # Disable mindmap generation (mindmaps ON by default)
--mindmap-format <format> # mermaid | ascii | both (default: both)
--model-parser <model> # haiku | sonnet | opus (default: haiku)
--model-extractor <model> # haiku | sonnet | opus (default: sonnet)
--model-formatter <model> # haiku | sonnet | opus (default: sonnet)
--model-mindmap <model> # haiku | sonnet | opus (default: sonnet)
--model-critic <model> # haiku | sonnet | opus (default: sonnet)
Examples (Basic Usage - Default Mindmaps):
/transcript meeting.vtt
/transcript standup.srt --output-dir ./docs/meetings/
/transcript notes.txt --format txt
/transcript meeting.vtt --domain software-engineering
Examples (Mindmap Control):
/transcript meeting.vtt --mindmap-format mermaid
/transcript meeting.vtt --mindmap-format ascii
/transcript meeting.vtt --mindmap-format both
/transcript meeting.vtt --no-mindmap
Examples (Model Selection):
/transcript meeting.vtt --model-extractor opus
/transcript meeting.vtt \
--model-parser haiku \
--model-extractor haiku \
--model-formatter haiku \
--model-mindmap haiku \
--model-critic haiku
/transcript meeting.vtt \
--model-parser haiku \
--model-formatter haiku \
--model-mindmap haiku
Option 2: Natural Language (Implicit)
"Process the transcript at /path/to/meeting.vtt"
"Extract action items from yesterday's team meeting"
"Analyze the quarterly review transcript and create a summary"
"Process the meeting transcript and generate mindmaps"
"Parse the standup notes without mindmaps"
"Create a Mermaid-only mindmap from the transcript"
"Use high-quality extraction for this transcript" (triggers --model-extractor opus)
Detection Algorithm:
- Scan for activation keywords (transcript, meeting, parse, extract)
- Extract file path from message (if present)
- Identify implied options (e.g., "without mindmaps" →
--no-mindmap)
- Map natural language to equivalent CLI command
- Execute Phase 1 via jerry CLI with detected parameters
Common Invocation Errors (F-001)
PURPOSE: Learn from common mistakes to avoid failed invocations and understand error recovery.
Error 1: Invalid File Path
What NOT to Do:
/transcript meeting.vtt
Error Output:
Error: Input file 'meeting.vtt' does not exist
Expected: Absolute path or path relative to current working directory
Example: /Users/me/transcripts/meeting.vtt
Correct Invocation:
/transcript /Users/me/transcripts/meeting.vtt
/transcript ./transcripts/meeting.vtt
Error 2: Unquoted Paths with Spaces
What NOT to Do:
uv run jerry transcript parse /Users/me/my meetings/meeting.vtt
Error Output:
Error: Invalid invocation - multiple positional arguments detected
Detected: ['/Users/me/my', 'meetings/meeting.vtt']
Solution: Quote file paths containing spaces
Correct Invocation:
uv run jerry transcript parse "/Users/me/my meetings/meeting.vtt"
Error 3: Missing Output Directory
What NOT to Do:
/transcript meeting.vtt --output-dir /nonexistent/path/
Error Output:
Error: Cannot create output directory '/nonexistent/path/'
Parent directory '/nonexistent/' does not exist
Solution: Ensure parent directory exists OR use default (./transcript-output/)
Correct Invocation:
/transcript meeting.vtt
mkdir -p /path/to/outputs/
/transcript meeting.vtt --output-dir /path/to/outputs/meeting-001/
Error 4: Invalid Domain Name
What NOT to Do:
/transcript meeting.vtt --domain engineering
Error Output:
Error: Unknown domain 'engineering'
Available domains: general, transcript, meeting, software-engineering,
software-architecture, product-management, user-experience,
cloud-engineering, security-engineering
Did you mean: software-engineering?
Correct Invocation:
/transcript meeting.vtt --domain software-engineering
Error 5: Conflicting Mindmap Flags
What NOT to Do:
/transcript meeting.vtt --no-mindmap --mindmap-format mermaid
Error Output:
Error: Conflicting flags detected
--no-mindmap: Disables all mindmap generation
--mindmap-format mermaid: Requests specific mindmap format
Solution: Remove one of these flags
Correct Invocation:
/transcript meeting.vtt --no-mindmap
/transcript meeting.vtt --mindmap-format mermaid
Input Parameters Reference
| Parameter | Type | Required | Default | Description |
|---|
input_file | string | Yes | - | Path to transcript file |
output_dir | string | No | ./transcript-output/ | Output directory for packet |
format | string | No | auto-detect | Force format: vtt, srt, txt |
domain | string | No | general | Context injection domain (9 available) |
confidence_threshold | float | No | 0.7 | Minimum confidence for extractions |
quality_threshold | float | No | 0.9 | ps-critic quality threshold |
--no-mindmap | flag | No | false | Disable mindmap generation |
--mindmap-format | string | No | "both" | Format: mermaid, ascii, both |
--model-parser | string | No | haiku | Model for ts-parser |
--model-extractor | string | No | sonnet | Model for ts-extractor |
--model-formatter | string | No | sonnet | Model for ts-formatter |
--model-mindmap | string | No | sonnet | Model for ts-mindmap-* |
--model-critic | string | No | sonnet | Model for ps-critic |
Model Selection
The transcript skill supports configurable models for each agent to optimize cost and quality.
Parameters
| Parameter | Default | Description |
|---|
--model-parser | haiku | Model for ts-parser (orchestration, routing) |
--model-extractor | sonnet | Model for ts-extractor (entity extraction) |
--model-formatter | sonnet | Model for ts-formatter (packet generation) |
--model-mindmap | sonnet | Model for ts-mindmap-* (visualization) |
--model-critic | sonnet | Model for ps-critic (quality review) |
Valid Model Values: haiku, sonnet, opus
Cost Optimization
Based on Anthropic Claude pricing (as of 2026-01-30) for 10,000 input tokens:
| Configuration | Estimated Cost | Quality Trade-off | Use Case |
|---|
| Default (mixed) | ~$0.12 | Balanced cost and quality | Recommended for most workflows |
| All haiku | ~$0.015 | 88% savings, lower extraction quality | Budget-constrained, simple transcripts |
| All sonnet | ~$0.15 | Baseline quality | Consistent quality across all agents |
| All opus | ~$0.75 | Highest quality, 6x cost | Critical meetings, high-stakes content |
Cost Breakdown (Default):
- ts-parser (haiku): ~$0.0025 - Simple orchestration
- ts-extractor (sonnet): ~$0.06 - Most token-intensive agent
- ts-formatter (sonnet): ~$0.03 - Template-based generation
- ts-mindmap-* (sonnet): ~$0.015 - Hierarchical reasoning
- ps-critic (sonnet): ~$0.015 - Quality evaluation
Usage Examples
Economy Mode (Minimize Cost)
uv run jerry transcript parse meeting.vtt \
--model-parser haiku \
--model-extractor haiku \
--model-formatter haiku \
--model-mindmap haiku \
--model-critic haiku
Quality Mode (Maximum Accuracy)
uv run jerry transcript parse meeting.vtt \
--model-extractor opus \
--model-critic opus
Balanced Mode (Default)
uv run jerry transcript parse meeting.vtt
Custom Mix (Targeted Optimization)
uv run jerry transcript parse meeting.vtt \
--model-formatter haiku \
--model-mindmap haiku
Recommendations
| Agent | Recommended Model | Rationale |
|---|
| ts-parser | haiku | Minimal semantic work - orchestration and routing only |
| ts-extractor | sonnet or opus | Core extraction quality - most critical for accuracy |
| ts-formatter | haiku or sonnet | Template-based generation - haiku sufficient if extraction is good |
| ts-mindmap-* | sonnet | Hierarchical reasoning - benefits from sonnet's structure understanding |
| ps-critic | sonnet | Quality evaluation - needs reliable judgment |
When to Upgrade to Opus:
- Legal, medical, or financial transcripts (high-stakes content)
- Poor automatic transcription quality (many errors)
Model Profiles
Model profiles provide quick-select configurations optimized for common use cases. Profiles replace manual configuration of individual --model-* flags.
Available Profiles
| Profile | Description | Use Case | Trade-off |
|---|
| economy | All haiku | High-volume processing, budget constraints | Lower extraction quality (~70-75% accuracy) |
| balanced | Mixed haiku/sonnet (default) | General purpose processing | Balanced cost and quality (~85-90% accuracy) |
| quality | Opus for critical agents | Critical meetings, complex content | Higher cost (~3.75x increase) |
| speed | All haiku | Real-time processing, quick turnaround | Quality for speed (~70-75% accuracy) |
Profile Model Assignments
| Agent | economy | balanced | quality | speed |
|---|
| ts-parser | haiku | haiku | sonnet | haiku |
| ts-extractor | haiku | sonnet | opus | haiku |
| ts-formatter | haiku | haiku | sonnet | haiku |
| ts-mindmap-* | haiku | sonnet | sonnet | haiku |
| ps-critic | haiku | sonnet | opus | haiku |
Usage
Select a Profile
uv run jerry transcript parse meeting.vtt --profile economy
uv run jerry transcript parse meeting.vtt --profile quality
uv run jerry transcript parse meeting.vtt --profile speed
Override Individual Models
Individual --model-* flags take precedence over --profile:
uv run jerry transcript parse meeting.vtt \
--profile economy \
--model-extractor opus
uv run jerry transcript parse meeting.vtt \
--profile quality \
--model-formatter haiku
Default Behavior
If neither --profile nor individual --model-* flags are specified:
- Default profile:
balanced
- Equivalent to:
--profile balanced
Priority Resolution
Model selection follows this precedence (highest to lowest):
- Explicit
--model-* flags (highest priority)
--profile flag
- Default profile (
balanced)
Example:
uv run jerry transcript parse meeting.vtt
uv run jerry transcript parse meeting.vtt --profile economy
uv run jerry transcript parse meeting.vtt --profile economy --model-extractor opus
Cost Comparison
Based on 10,000 input tokens:
| Profile | Estimated Cost | vs. Balanced |
|---|
| economy | ~$0.015 | 88% savings |
| balanced (default) | ~$0.12 | Baseline |
| quality | ~$0.45 | 3.75x increase |
| speed | ~$0.015 | 88% savings |
When to Use Each Profile
economy:
- High-volume batch processing
- Budget constraints
- Simple transcripts with minimal context
- Non-critical content
balanced (default):
- General purpose processing
- Most workflows
- Good cost/quality trade-off
- Recommended starting point
quality:
- Critical meetings (executive, legal, medical)
- Complex technical discussions
- Poor transcription quality (many errors)
- High-stakes content requiring accuracy
speed:
- Real-time processing needs
- Quick turnaround requirements
- Low-latency workflows
- Same cost as economy, emphasizes speed over quality
- Complex domain-specific terminology
- Critical meetings requiring maximum accuracy
When to Use Haiku:
- Simple, well-structured transcripts
- Budget constraints
- Low-stakes internal meetings
- Good automatic transcription quality
Output Structure (ADR-002 + v2.0 Hybrid)
transcript-{id}/
├── canonical/ # v2.0: Hybrid parser output
│ ├── canonical-transcript.json # Full parsed transcript
│ ├── index.json # Chunk index with metadata
│ └── chunks/ # Chunked segments (500 per file)
│ ├── chunk-000.json # Segments 0-499
│ ├── chunk-001.json # Segments 500-999
│ └── ...
├── 00-index.md # Navigation hub (~2K tokens)
├── 01-summary.md # Executive summary (~5K tokens)
├── 02-transcript.md # Full transcript (may split)
├── 03-speakers.md # Speaker directory
├── 04-action-items.md # Action items with citations
├── 05-decisions.md # Decisions with context
├── 06-questions.md # Open questions
├── 07-topics.md # Topic segments
├── 08-mindmap/ # Mindmap directory (default: enabled, per ADR-006)
│ ├── mindmap.mmd # Mermaid format (if --mindmap-format mermaid or both)
│ └── mindmap.ascii.txt # ASCII format (if --mindmap-format ascii or both)
└── _anchors.json # Anchor registry for linking
v2.0 Chunked Structure (index.json)
{
"schema_version": "1.0",
"generated_at": "2026-01-30T18:00:00Z",
"total_segments": 710,
"total_chunks": 4,
"chunk_size": 500,
"target_tokens": 18000,
"duration_ms": 2263888,
"speakers": {
"count": 3,
"list": ["Alex Johnson", "Sam Chen", "Jordan Lee"],
"segment_counts": {"Alex Johnson": 459, "Sam Chen": 156, "Jordan Lee": 95}
},
"chunks": [
{
"chunk_id": "chunk-001",
"segment_range": [1, 229],
"timestamp_range": {"start_ms": 3528, "end_ms": 721925},
"speaker_counts": {"Alex Johnson": 151, "Sam Chen": 39, "Jordan Lee": 39},
"word_count": 2193,
"file": "chunks/chunk-001.json"
}
]
}
Key Fields:
target_tokens: When set (e.g., 18000), uses token-based chunking. When null, uses segment-based (500 segs/chunk).
chunk_size: Fallback for segment-based mode (used when target_tokens is null).
- See DISC-001 for ~22% JSON serialization overhead (18K target → ~22K actual).
Chunk Token Budget (v2.1 - EN-026)
| Parameter | Value | Source |
|---|
| Claude Code Read limit | 25,000 tokens | GitHub Issue #4002 |
| Target tokens per chunk | 18,000 tokens | 25% safety margin |
| Token counting | tiktoken p50k_base | Best Claude approximation |
Note: Prior to v2.1, chunks used segment-based splitting (500 segments per chunk).
v2.1 uses token-based splitting to ensure chunks fit within Claude Code's Read tool limits.
This fixes BUG-001 where large transcripts produced chunks exceeding the 25K token limit.
Token Budget Compliance (ADR-004)
| Limit | Tokens | Action |
|---|
| Soft | 31,500 | Split at ## heading |
| Hard | 35,000 | Force split |
Model-Agnostic Output Requirements (ADR-007)
CRITICAL: Output structure MUST be identical regardless of which LLM model (Sonnet, Opus, Haiku) executes the skill. ADR-007 defines the golden template specification.
MUST-CREATE Files (Exactly 8 Core Files)
| Number | File | Description |
|---|
| 00 | 00-index.md | Navigation hub and metadata |
| 01 | 01-summary.md | Executive summary |
| 02 | 02-transcript.md | Full formatted transcript (splittable) |
| 03 | 03-speakers.md | Speaker directory |
| 04 | 04-action-items.md | Action items with citations |
| 05 | 05-decisions.md | Decisions with context |
| 06 | 06-questions.md | Open and answered questions |
| 07 | 07-topics.md | Topic hierarchy |
Also Required: _anchors.json (anchor registry)
MUST-NOT-CREATE Files (Validation Failure)
| Forbidden Pattern | Reason |
|---|
*-timeline.md | Not part of ADR-002 schema |
*-sentiment.md | Not part of ADR-002 schema |
*-analysis.md | Not part of ADR-002 schema |
08-*.md | 08 reserved for mindmap directory |
Unnumbered *.md | All core files must be numbered 00-07 |
Anchor Format (MUST USE)
| Entity | Pattern | Valid | Invalid |
|---|
| Segment | seg-NNN | seg-001 | segment-001, SEG-001 |
| Speaker | spk-{slug} | spk-alice-smith | speaker-alice |
| Action | act-NNN | act-001 | AI-001, ACT-001 |
| Decision | dec-NNN | dec-001 | DEC-001 |
| Question | que-NNN | que-001 | QUE-001 |
| Topic | top-NNN | top-001 | TOP-001 |
NNN = 3-digit, zero-padded (001-999)
Citation Format (MUST USE)
> "{QUOTED_TEXT}"
>
> -- [{SPEAKER}](03-speakers.md#{spk-slug}), [[{TIMESTAMP}]](02-transcript.md#{seg-NNN})
FORBIDDEN: Links to canonical-transcript.json (file too large for LLM context)
Navigation Links (MUST INCLUDE)
Every entity file (01-07) MUST include:
## Navigation
- [Back to Index](00-index.md)
- [Previous: {PREV_FILE_NAME}]({PREV_FILE}.md)
- [Next: {NEXT_FILE_NAME}]({NEXT_FILE}.md)
Reference: See ADR-007 for complete specification.
Tool Example: Writing Packet Files
ts-formatter generates packet files using Write tool:
# Create 00-index.md
Invoke Write tool with:
- file_path: "<packet-dir>/00-index.md"
- content: (generated index content with navigation links)
# Create 01-summary.md
Invoke Write tool with:
- file_path: "<packet-dir>/01-summary.md"
- content: (executive summary with key findings)
# Create 04-action-items.md
Invoke Write tool with:
- file_path: "<packet-dir>/04-action-items.md"
- content: (action items with citations and anchors)
Content structure example (04-action-items.md):
# Action Items
<!-- Anchor: #act-001 -->
## 1. Implement user authentication
**Assigned to:** Alice
**Priority:** High
**Due date:** Next sprint
**Source:**
- Timestamp: [00:15:32]
- Speaker: Alice (#spk-001)
- Utterance: #utt-042
**Context:**
> "We need to implement user authentication before the beta launch. I'll take this on for next sprint."
---
<!-- Anchor: #act-002 -->
## 2. Fix navigation bug
...
File size validation:
After writing each file:
Count tokens using Claude's tokenizer
IF tokens > 35000:
Split at semantic boundary (## heading)
Create part-002, part-003, etc.
Agent File Consumption Rules (CRITICAL)
MANDATORY: Agents MUST follow these file consumption rules to prevent context window overflow.
Violating these rules causes degraded performance and potential failures.
Files Agents SHOULD Read
| File | Typical Size | Agent | Purpose |
|---|
index.json | ~8KB | ts-extractor, ts-formatter | Metadata, speaker list, chunk references |
chunks/chunk-*.json | ~130KB each | ts-extractor | Actual transcript data in manageable pieces |
extraction-report.json | ~35KB | ts-formatter, ps-critic | Entity extraction results |
packet/*.md | Variable | ps-critic | Generated Markdown files for quality review |
Files Agents MUST NEVER Read
| File | Typical Size | Why Forbidden |
|---|
canonical-transcript.json | ~930KB | TOO LARGE - will overwhelm context window, cause context rot, degrade agent performance |
Rationale
The canonical-transcript.json file is generated for:
- Reference/archive purposes - Human inspection of full parsed output
- Programmatic access by Python code - CLI tools that process outside LLM context
- NOT for LLM agent consumption - File size exceeds safe context limits
The chunking architecture (DISC-009) was specifically designed to solve the large file problem:
- Each chunk is < 150KB (fits comfortably in context)
- Python parser creates chunks; LLM agents consume chunks
- This prevents the 99.8% data loss experienced with agent-only architecture
Agent-Specific File Access
| Agent | Reads | Never Reads |
|---|
| ts-parser | Input VTT/SRT/TXT file | - |
| ts-extractor | index.json, chunks/*.json | canonical-transcript.json |
| ts-formatter | index.json, extraction-report.json | canonical-transcript.json |
| ps-critic | All packet/*.md files, quality-review.md | canonical-transcript.json |
Orchestration Flow
L1: Step-by-Step Pipeline (v2.0 Hybrid)
STEP 1: PARSE + CHUNK (ts-parser v2.0)
──────────────────────────────────────
Input: Raw transcript file (VTT/SRT/TXT)
Process:
1. Detect format (VTT header check)
2. IF VTT:
- Delegate to Python parser (Bash tool)
- Validate output schema
- Chunk to 500-segment files
3. ELSE (SRT/TXT):
- Use LLM parsing (fallback)
- Chunk if large file
Output: index.json + chunks/chunk-NNN.json
Errors: Python failure → fallback to LLM parsing
STEP 2: EXTRACT (ts-extractor)
──────────────────────────────
Input: index.json + chunks/*.json (NEVER canonical-transcript.json)
Process:
1. Read index.json for metadata and chunk listing
2. Process each chunk sequentially for entity extraction
3. Extract entities with confidence scores and citations
Output: extraction-report.json
Errors: Low confidence extractions → flag for review
STEP 3: FORMAT (ts-formatter)
─────────────────────────────
Input: index.json + extraction-report.json (NEVER canonical-transcript.json)
Output: packet/ directory (8 files per ADR-002)
Errors: Token overflow → split files automatically (ADR-004)
STEP 3.5: MINDMAP GENERATION (ts-mindmap-*, conditional - ADR-006)
──────────────────────────────────────────────────────────────────
Condition: --no-mindmap flag NOT set (mindmaps ON by default)
Input: ts_extractor_output.extraction_report_path + ts_formatter_output.packet_path
Process:
1. IF --no-mindmap flag is NOT set: # Default behavior
- IF --mindmap-format == "mermaid" OR "both" (default):
Invoke ts-mindmap-mermaid
Output: 08-mindmap/mindmap.mmd
- IF --mindmap-format == "ascii" OR "both" (default):
Invoke ts-mindmap-ascii
Output: 08-mindmap/mindmap.ascii.txt
2. ELSE:
- Skip mindmap generation (user opted out)
- ts_mindmap_output.overall_status = "skipped"
Output: ts_mindmap_output state key
Errors: Graceful degradation - continue with warning, provide regeneration instructions
STEP 4: REVIEW (ps-critic)
──────────────────────────
Input: All generated files
Output: quality-review.md
Errors: Score < 0.90 → report issues for human review
L2: State Passing Between Agents (v2.0)
PURPOSE: State keys provide persistence across agent boundaries, enabling:
- Error recovery - Agents can resume from last checkpoint
- Debugging - Full pipeline trace in state history
- Quality assurance - ps-critic validates entire pipeline state
| Agent | Output Key | Passed To | Purpose |
|---|
| ts-parser v2.0 | ts_parser_output | ts-extractor | Parsing results + chunk metadata |
| ts-extractor | ts_extractor_output | ts-formatter | Extraction report + stats |
| ts-formatter | ts_formatter_output | ts-mindmap-*, ps-critic | Packet location + file manifest |
| ts-mindmap-* | ts_mindmap_output | ps-critic | Mindmap paths + generation status |
| ps-critic | quality_output | User/Orchestrator | Quality validation results |
State Schema (v2.0):
ts_parser_output:
canonical_json_path: string
index_json_path: string
chunks_dir: string
chunk_count: integer
format_detected: vtt|srt|plain
parsing_method: python|llm
segment_count: integer
speaker_count: integer
duration_ms: integer|null
validation_passed: boolean
warnings: string[]
errors: string[]
fallback_triggered: boolean
ts_extractor_output:
extraction_report_path: string
action_count: integer
decision_count: integer
question_count: integer
topic_count: integer
speaker_count: integer
high_confidence_ratio: float
average_confidence: float
chunks_processed: integer
input_format: "chunked"|"single_file"
tier_1_count: integer
tier_2_count: integer
tier_3_count: integer
ts_formatter_output:
packet_path: string
files_created: string[]
split_files: integer
total_tokens: integer
max_file_tokens: integer
anchor_count: integer
backlink_count: integer
all_files_under_limit: boolean
ts_mindmap_output:
enabled: boolean
format_requested: string
mermaid:
path: string | null
status: string
error_message: string | null
topic_count: integer
deep_link_count: integer
syntax_validated: boolean
ascii:
path: string | null
status: string
error_message: string | null
topic_count: integer
max_line_width: integer
box_drawing_valid: boolean
overall_status: string
regeneration_command: string | null
quality_output:
quality_score: float
passed: boolean
issues: string[]
recommendations: string[]
criteria_scores: dict
mindmap_criteria_applied: boolean
artifacts_validated: string[]
validation_timestamp: string
Error State Structures (F-002)
PURPOSE: Document how agents communicate errors through state keys.
Enables downstream agents to detect and handle failures gracefully.
Error State Schema
When an agent encounters an error, it MUST populate error-specific fields in its output state key:
{agent}_output:
status: string
errors: string[]
warnings: string[]
recovery_possible: boolean
recovery_command: string | null
recovery_instructions: string | null
error_context: dict | null
Error State Examples by Agent
ts-parser Error (Python Parser Failure):
ts_parser_output:
status: "partial"
canonical_json_path: "/path/to/canonical-transcript.json"
index_json_path: "/path/to/index.json"
chunks_dir: "/path/to/chunks/"
chunk_count: 3
errors:
- "Python VTT parser failed: UnicodeDecodeError at line 42"
warnings:
- "Fallback to LLM parsing - increased cost and latency"
fallback_triggered: true
recovery_possible: false
recovery_instructions: "LLM fallback completed successfully. No action required."
error_context:
python_error_type: "UnicodeDecodeError"
failed_encoding: "utf-8"
attempted_fallback_encodings: ["windows-1252", "iso-8859-1"]
fallback_method: "llm"
fallback_model: "sonnet"
ts-extractor Error (Context Overflow):
ts_extractor_output:
status: "failed"
extraction_report_path: null
errors:
- "Context window exceeded: chunk-042.json is 45,000 tokens (limit: 35,000)"
- "Cannot process chunk without splitting"
warnings: []
recovery_possible: true
recovery_command: "uv run jerry transcript parse <file> --chunk-target-tokens 15000"
recovery_instructions: >
Re-run parsing with smaller chunk size to prevent context overflow.
Use --chunk-target-tokens 15000 (down from default 18000) to reduce chunk size.
error_context:
failed_chunk_id: "chunk-042"
failed_chunk_tokens: 45000
chunk_token_limit: 35000
suggestion: "Lower --chunk-target-tokens parameter"
ts-formatter Error (File Write Failure):
ts_formatter_output:
status: "failed"
packet_path: "/output/transcript-meeting-001/"
files_created:
- "00-index.md"
- "01-summary.md"
- "02-transcript.md"
files_failed:
- "03-speakers.md"
- "04-action-items.md"
- "05-decisions.md"
- "06-questions.md"
- "07-topics.md"
errors:
- "IOError: Permission denied writing to /output/transcript-meeting-001/03-speakers.md"
warnings: []
recovery_possible: true
recovery_command: "chmod 755 /output/transcript-meeting-001/ && /transcript resume --from formatting"
recovery_instructions: >
Fix directory permissions and resume formatting phase.
Existing files (00-02) will be skipped if valid.
error_context:
permission_error_path: "/output/transcript-meeting-001/03-speakers.md"
directory_permissions: "dr-xr-xr-x"
required_permissions: "drwxr-xr-x"
ts-mindmap-mermaid Error (Syntax Validation Failure):
ts_mindmap_output:
enabled: true
format_requested: "both"
mermaid:
path: "/output/08-mindmap/mindmap.mmd"
status: "failed"
error_message: "Mermaid syntax validation failed: Invalid node syntax at line 12"
topic_count: 0
deep_link_count: 0
syntax_validated: false
ascii:
path: "/output/08-mindmap/mindmap.ascii.txt"
status: "complete"
error_message: null
topic_count: 47
max_line_width: 79
box_drawing_valid: true
overall_status: "partial"
errors:
- "Mermaid mindmap generation failed: Syntax error (markdown link in node)"
warnings:
- "Mermaid mindmap unavailable - ASCII mindmap generated successfully"
recovery_possible: true
regeneration_command: "uv run jerry transcript mindmap --format mermaid --packet-path /output/"
recovery_instructions: >
Mermaid syntax error likely caused by markdown links in node text.
The ts-mindmap-mermaid agent uses plain text ONLY in nodes per ADR-003 Section 5.3.
ASCII mindmap is valid and can be used. To retry Mermaid generation:
1. Review deep link reference block format
2. Ensure no markdown syntax in topic text
3. Run regeneration command above
quality_output Error (Quality Gate Failure):
quality_output:
quality_score: 0.68
passed: false
issues:
- "T-001: Missing timestamps in 23% of segments"
- "T-004: Low citation coverage (42% of extractions lack source anchors)"
- "T-006: Token limit exceeded in 02-transcript-part-003.md (37,500 tokens)"
- "MM-002: Mermaid mindmap missing deep link reference block"
recommendations:
- "Re-run parsing to fix timestamp gaps"
- "Ensure ts-extractor includes segment_id in all citations"
- "Re-run ts-formatter with stricter token splitting (31.5K soft limit)"
- "Add deep link reference block to Mermaid mindmap per ADR-003 Section 5.3"
criteria_scores:
"T-001": 0.77
"T-002": 0.95
"T-003": 0.90
"T-004": 0.42
"T-005": 0.85
"T-006": 0.50
"MM-002": 0.00
mindmap_criteria_applied: true
artifacts_validated:
- "00-index.md"
- "01-summary.md"
- "02-transcript-part-001.md"
- "02-transcript-part-002.md"
- "02-transcript-part-003.md"
- "08-mindmap/mindmap.mmd"
- "08-mindmap/mindmap.ascii.txt"
validation_timestamp: "2026-01-30T19:15:00Z"
errors: []
warnings:
- "Quality score 0.68 below threshold 0.90"
status: "failed"
recovery_possible: true
recovery_command: null
recovery_instructions: >
Address the 4 high-priority issues listed above and re-run ps-critic.
Critical failures:
1. T-004 (citation coverage) - Re-run ts-extractor with citation enforcement
2. T-006 (token limits) - Re-run ts-formatter with --split-at-soft-limit flag
3. MM-002 (deep links) - Re-run ts-mindmap-mermaid with reference block generation
Propagated Error State (Multi-Agent Failure)
When an error in one agent cascades to downstream agents:
ts_parser_output:
status: "failed"
errors:
- "Fatal: Input file is corrupted (invalid WebVTT structure)"
recovery_possible: false
recovery_instructions: "Provide a valid VTT, SRT, or TXT file"
ts_extractor_output:
status: "failed"
errors:
- "Missing required input: ts_parser_output.index_json_path"
- "Cannot extract entities without parsed transcript"
recovery_possible: false
recovery_instructions: "Fix ts-parser errors before proceeding to extraction"
ts_formatter_output:
status: "skipped"
errors:
- "Skipped due to upstream failure: ts-extractor.status = 'failed'"
recovery_possible: false
overall_pipeline_status: "failed"
failed_phase: "parsing"
recovery_instructions: "Fix input file and restart pipeline from beginning"
State Passing Error Handling
Error Propagation Rules
| Error Type | Behavior | State Impact |
|---|
| Fatal Error | Stop pipeline immediately | Set status: "failed" in current agent output |
| Warning | Continue pipeline | Add to warnings[] array, log in state |
| Validation Failure | Agent-specific decision | ts-parser: fallback to LLM; ts-extractor: skip low-confidence |
| Missing Input | Fatal error | Cannot proceed, report missing dependency |
State Validation at Agent Boundaries
Before ts-extractor:
REQUIRED from ts_parser_output:
- index_json_path (must exist)
- chunks_dir (must exist)
- chunk_count > 0
- validation_passed == true
Before ts-formatter:
REQUIRED from ts_extractor_output:
- extraction_report_path (must exist)
- action_count == len(action_items) in report (INV-EXT-001)
- decision_count == len(decisions) in report (INV-EXT-001)
- question_count == len(questions) in report (INV-EXT-001)
Before ps-critic:
REQUIRED from ts_formatter_output:
- packet_path (directory must exist)
- files_created (all files must exist)
- all_files_under_limit == true (ADR-004 compliance)
State Recovery Scenarios (F-003)
PURPOSE: Provide comprehensive recovery procedures for all known failure modes.
Enables self-service recovery without requiring expert intervention.
Scenario 1: Python Parser Failure (Encoding Issues)
Symptom:
Error: Python VTT parser failed: UnicodeDecodeError
Fallback: LLM parsing succeeded (increased cost)
Root Cause: VTT file uses non-UTF-8 encoding (e.g., Windows-1252, UTF-16).
Recovery:
uv run jerry transcript parse meeting.vtt --force-llm
iconv -f windows-1252 -t utf-8 meeting.vtt > meeting-utf8.vtt
uv run jerry transcript parse meeting-utf8.vtt
Prevention: Ensure VTT files are UTF-8 encoded before processing.
Scenario 2: Context Window Overflow (Chunk Too Large)
Symptom:
Error: Context window exceeded: chunk-042.json is 45,000 tokens (limit: 35,000)
Status: ts-extractor failed
Root Cause: Chunk exceeds Claude Code Read tool limit (25K tokens). Occurs when transcript has very long monologues.
Recovery:
uv run jerry transcript parse meeting.vtt --chunk-target-tokens 12000 --output-dir ./output-v2/
Prevention: Use --chunk-target-tokens 15000 for transcripts with long segments.
Scenario 3: File Write Permission Denied
Symptom:
Error: IOError: Permission denied writing to /output/transcript-meeting-001/03-speakers.md
Status: ts-formatter failed (partial completion)
Files created: 00-02
Files failed: 03-07
Root Cause: Output directory or parent directory has incorrect permissions.
Recovery:
chmod 755 /output/transcript-meeting-001/
uv run jerry transcript resume --from formatting --packet-path /output/transcript-meeting-001/
chmod 755 /output/
uv run jerry transcript parse meeting.vtt --output-dir /output/meeting-002/
Prevention: Ensure write permissions on output directory before invoking skill.
Scenario 4: Quality Gate Failure (Score < 0.90)
Symptom:
Quality Score: 0.68 (threshold: 0.90)
Status: quality_output.passed = false
Issues:
- T-004: Low citation coverage (42%)
- T-006: Token limit exceeded in 02-transcript-part-003.md
Root Cause: Extraction quality issues or token budget violations.
Recovery:
Step 1: Review quality-review.md for specific issues
cat /output/transcript-meeting-001/quality-review.md
Step 2: Address each issue:
For T-004 (citation coverage):
uv run jerry transcript resume --from extraction --enforce-citations
For T-006 (token limits):
uv run jerry transcript resume --from formatting --split-at-soft-limit
Step 3: Re-run quality review:
uv run jerry transcript resume --from quality-review
Prevention: Use --model-extractor opus for better extraction quality.
Scenario 5: Agent Timeout (Long Transcripts)
Symptom:
Error: Agent timeout after 300 seconds
Status: ts-extractor failed
Progress: Processed 8/15 chunks before timeout
Root Cause: Very large transcript (> 10,000 segments) exceeds default timeout.
Recovery:
uv run jerry transcript parse meeting.vtt --extractor-timeout 600
uv run python scripts/split_vtt.py meeting.vtt --max-duration 60
uv run jerry transcript parse meeting-part-001.vtt
uv run jerry transcript parse meeting-part-002.vtt
Prevention: For transcripts > 2 hours, consider splitting into segments.
Scenario 6: Partial Extraction (Low Confidence)
Symptom:
Warning: 45% of action items have confidence < 0.70
Status: ts-extractor succeeded (with warnings)
Root Cause: Ambiguous language, implicit action items, or poor transcript quality.
Recovery:
uv run jerry transcript parse meeting.vtt --model-extractor opus
uv run jerry transcript parse meeting.vtt --confidence-threshold 0.5
cat /output/extraction-report.json | jq '.action_items[] | select(.confidence < 0.70)'
Prevention: Improve automatic transcription quality (better audio, less background noise).
Scenario 7: Mindmap Syntax Validation Failure
Symptom:
Error: Mermaid syntax validation failed: Invalid node syntax at line 12
Status: ts_mindmap_output.mermaid.status = "failed"
Status: ts_mindmap_output.ascii.status = "complete"
Root Cause: Markdown links used in Mermaid node text (ADR-003 limitation).
Recovery:
uv run jerry transcript mindmap --format mermaid --packet-path /output/ --plain-text-only
cat /output/08-mindmap/mindmap.ascii.txt
Prevention: ts-mindmap-mermaid agent should strip markdown syntax before node generation.
Scenario 8: File Conflict (Output Already Exists)
Symptom:
Error: Output directory already exists: /output/transcript-meeting-001/
Conflict: 00-index.md, 01-summary.md (8 files total)
Root Cause: Previous run output not cleared before re-running.
Recovery:
rm -rf /output/transcript-meeting-001/
uv run jerry transcript parse meeting.vtt --output-dir /output/transcript-meeting-001/
uv run jerry transcript parse meeting.vtt --output-dir /output/transcript-meeting-001-$(date +%Y%m%d-%H%M%S)/
uv run jerry transcript parse meeting.vtt --output-dir /output/transcript-meeting-001/ --merge
Prevention: Use --output-dir with unique names or timestamps.
Scenario 9: Missing Dependencies (Python Modules)
Symptom:
Error: ModuleNotFoundError: No module named 'tiktoken'
Status: ts-parser failed (cannot perform token counting)
Root Cause: UV environment missing required Python dependencies.
Recovery:
uv sync
uv pip list | grep tiktoken
uv run jerry transcript parse meeting.vtt
Prevention: Run uv sync after pulling changes or switching branches.
Scenario 10: Orchestration State Corruption
Symptom:
Error: State key mismatch: ts_extractor_output.action_count (23) != len(action_items) in extraction-report.json (25)
Violation: INV-EXT-001 (entity count consistency)
Status: ts-formatter refused to proceed
Root Cause: Agent violated state schema invariant (likely a bug).
Recovery: