Todo Backlog

EPGOAT Documentation - Work In Progress

TODO Backlog - Documentation Work

Purpose: Central index of all pending documentation work Last Updated: 2025-11-10 (added GitHub Actions billing issue as CRITICAL)

Tier Naming Update (2025-11-07): The tier system has been renamed from "bottom/middle/top tier" to KID/BILLY/GOAT tiers: - KID tier = Minimal features (previously "bottom tier") - BILLY tier = Mid-level features (previously "middle tier") - GOAT tier = Full-featured (previously "top tier")

Business requirements below use the original naming. See Documentation/10-Projects/Active/Architecture-Workflow-Redesign.md for current implementation.


How to Use This File

For You:

  • This is your work inbox - Check here to see what needs doing
  • Pick items based on priority and deadline
  • Click links to see full details
  • Work through items at your own pace

For Claude:

  • Check this file at every session start
  • Show user a summary of pending work
  • Update this file when creating new work items
  • Mark items as done when complete
  • Move to archive after 1 week in completed section

🔴 CRITICAL (Do Immediately)

[Fix GitHub Actions Billing/Spending Limit Issue]

  • Status: NOT STARTED
  • Effort: 15-30 minutes (account configuration)
  • Deadline: ASAP (blocking all GitHub Actions workflows)
  • Priority: 🔴 CRITICAL - All automated workflows blocked
  • Added: 2025-11-10
  • Context: GitHub Actions workflows failing with error: "The job was not started because recent account payments have failed or your spending limit needs to be increased. Please check the 'Billing & plans' section in your settings"

Impact: - ❌ Provider onboarding workflow blocked - ❌ Cleanup onboarding workflow blocked - ❌ CI/CD test pipeline blocked - ❌ Team sync workflows blocked - ❌ All automated processes halted

Required Actions: 1. Go to GitHub account SettingsBilling and plans 2. Check Actions minutes usage for current billing period 3. Update payment method if failed/expired 4. Increase spending limit if exhausted 5. Review monthly usage patterns to prevent recurrence 6. Consider upgrading plan if free tier insufficient

Workaround (Temporary): - Use local script execution instead of GitHub Actions - Example: python -m epgoat.cli.cleanup_onboarding (runs locally with .env credentials) - All scripts work locally - GitHub Actions provide convenience, not required functionality

Next Steps: - [ ] Check GitHub billing dashboard - [ ] Update payment method or increase spending limit - [ ] Verify workflows can run successfully - [ ] Document monthly Actions usage for budgeting - [ ] Consider cost optimization (workflow efficiency, caching, etc.)


  • [ ] **Fix Documentation and split it out between LLM and Human readable
  • [ ] Architecture & Workflow Redesign - IMPLEMENTATION
  • Status: Design complete, awaiting implementation start
  • Documentation: Architecture-Workflow-Redesign.md
  • Implementation Plan: 2025-01-05-architecture-workflow-redesign.md
  • Current Phase: Awaiting final approvals to begin Phase 1
  • Target Completion: 2025-02-05 (4 weeks from start)
  • Next Steps: Begin Phase 1 implementation (Infrastructure Setup: Supabase + R2)
  • [ ] Discuss https://github.com/iptv-org and how we can leverage
  • [ ] **Imperitive for go-live. We need to offer a few month (or free 3 month promo) if a user gets someone else to sign up for service using their code. once a new account is created and paid, the referrer will automatically get time added to their account. if their account has no time, then the time starts today. this will help spread word of mouth
  • [ ] **I'd like to nail down the different packages offered, their names, and their pricing. how about, each 12 month subscription to any bottom or middle tier account gets their first 2 weeks of service at our top tier, then it drops back down to the tier they chose. afterwards, they'll have the option to upgrade their account. upgrade will be the top tier price, less the prorated (by days) amount they paid for their current service. users can upgrade at any time during service.

📋 Architecture & Workflow Redesign - Discussion Document

Priority: CRITICAL Type: Strategic Planning Session Scheduled: Wednesday (when tokens renewed) Duration: 60-90 minutes

Overview

We need to establish a reliable, production-ready EPG generation system. This discussion covers database architecture, parsing strategy, output quality, and workflow optimization.


1. Database Infrastructure Concerns

Current Problem: Cannot easily view/query data in Supabase PostgreSQL

Proposal: Consider migrating to MySQL or Supabase. open to self hosting on a vps

Reasons: - Need visual database management tools (phpMyAdmin-like) - Want to leverage DataGrip for complex queries - Need better visibility into data for debugging and optimization - D1 lacks robust tooling ecosystem

Discussion Points: - [ ] Pros/cons of MySQL vs D1 vs other options (PostgreSQL?) - [ ] Migration complexity and downtime - [ ] Oracle Free Tier VPN + mySQL/phpMyAdmin? - [ ] Cost implications (hosting, maintenance) - [ ] Performance considerations at scale - [ ] Cloudflare integration trade-offs - [ ] Local development workflow with MySQL - [ ] mySQL version should support indexing


2. Database Schema Redesign

Goal: Create a more structured, normalized schema that supports reliable EPG generation

Proposed Table Structure:

┌─────────────────┐
│  ChannelNames   │  ← One record per unique channel name
├─────────────────┤
│ id (PK)         │
│ channel_name    │
│ provider        │
│ parsed_data_id  │─────┐
│ tvg_id          │     │
│ created_at      │     │
│ updated_at      │     │
└─────────────────┘     │
                        │
                        ▼
┌─────────────────┐   ┌─────────────────┐
│   ParsedData    │   │  EventDetails   │
├─────────────────┤   ├─────────────────┤
│ id (PK)         │   │ id (PK)         │
│ event_detail_id │───│ (TheSportsDB)   │
│ raw_title       │   │ event_name      │
│ parsed_date     │   │ start_time      │
│ parsed_time     │   │ league          │
│ parsed_teams    │   │ sport           │
│ parsed_league   │   │ venue           │
│ confidence      │   │ etc...          │
│ match_reason    │   └─────────────────┘
│ created_at      │
└─────────────────┘
         │
         ▼
┌─────────────────┐
│    EPGData      │  ← Final EPG output data
├─────────────────┤
│ id (PK)         │
│ channel_name_id │
│ title           │
│ description     │  ← RICH TRIAGE DATA
│ start_time      │
│ end_time        │
│ category        │
│ icon            │
│ episode_num     │
│ confidence      │
│ match_status    │
│ created_at      │
└─────────────────┘

Key Concepts: - ChannelNames: One record per unique channel name + provider combo - ParsedData: Everything extracted from the parser, regardless of match success - EventDetails: Enriched data from various APIs - EPGData: Final output-ready data (one-to-one with ChannelNames)

Benefits: - Clear separation of parsing, matching, and output stages - Historical tracking of parse attempts - Easy to identify channels that need manual attention - Supports incremental updates efficiently

Discussion Points: - [ ] Table normalization strategy (are we over/under normalized?) - [ ] Indexing strategy for performance - [ ] Foreign key constraints and cascade rules - [ ] Handling duplicate channel names across providers - [ ] Soft delete strategy (record_status fields) - [ ] Audit history requirements


3. Parser-First Workflow

Current Problem: Matching happens too early, limiting what we can extract

Proposed Workflow:

1. Parse M3U → Extract EVERYTHING possible
   ↓
2. Store in ParsedData table (ALL live event channels, matched or not)
   ↓
3. Attempt to match with EventDetails
   ↓
4. Generate EPG data for EVERYTHING (not just matches)
   ↓
5. Output EPG + filtered M3U

Key Principle: "Parse everything, match what we can, output everything"

Parser Enhancement Goals: - Extract dates (all formats: ISO, natural language, timezone-aware) - Extract times (12h/24h, timezone abbreviations) - Extract team names (vs, @, -, etc.) - Extract league identifiers - Extract event types (game, highlights, replay, etc.) - Extract channel number/identifier - Store confidence scores for each extracted field

Discussion Points: - [ ] What regex patterns can we improve? - [ ] Should we use NLP libraries for better text parsing? - [ ] Determine where in the proceess an LLM (Claude Haiku) is best suited - [ ] How do we handle ambiguous data (e.g., "10:00" without timezone)? - [ ] Fallback strategies when extraction fails - [ ] Performance implications of heavier parsing


4. EPG Output Improvements

Goal: Make EPG data useful for troubleshooting and validation

4.1 Filtered M3U Generation

Proposal: Generate companion M3U file with only channels that contain live events

Features: - Include ONLY channels that appear in EPG - Maintain matching tvg-id values - Enable easy testing in TiviMate (load M3U + EPG together) - Quickly spot issues without scrolling through thousands of channels

File Naming:

Original:  tps_playlist.m3u → tps_epg.xml
Generated: tps_playlist.m3u → tps.xml + tps.m3u

4.2 Rich Description Field

Proposal: Use EPG description field for triage/debugging data

Example Description Fields:

<!-- SUCCESSFUL MATCH -->
<desc>
✅ MATCHED (95% confidence)
Source: TPS Channel "NBA 01: Lakers vs Celtics 8:00 PM ET"
Parsed: Lakers vs Celtics @ 2025-11-03 20:00 ET
Matched: TheSportsDB Event #12345
Reason: Exact team name match + time within 30min
League: NBA (Basketball)
Provider: TPS
</desc>

<!-- NO MATCH -->
<desc>
⚠️ NO MATCH (Generic Channel)
Source: TPS Channel "Sports News 24/7"
Parsed: No event data extracted
Reason: Generic channel name (no date/time/teams)
League: N/A
Provider: TPS
</desc>

<!-- PARTIAL MATCH -->
<desc>
🔶 PARTIAL MATCH (60% confidence)
Source: TPS Channel "College Football 02"
Parsed: Sport=Football, League=NCAAF
Matched: Generic "College Football" placeholder
Reason: No specific teams/time extracted
League: NCAAF (Football)
Provider: TPS
</desc>

Benefits: - Instant visibility into matching quality from TV - Easy identification of patterns that need work - Quick validation of confidence scoring - Debugging without SSH/database access

Discussion Points: - [ ] Should we use emojis in descriptions? (✅⚠️🔶) - [ ] How verbose should descriptions be? - [ ] Exactly what information should be included? - [ ] Make this a debug mode toggle? - [ ] Include parse performance metrics? (parse time, DB query time)

4.3 Smarter EPG generation

Proposal: Since each channel will have a record, we will know when a channel on a specific playlist needs updated... we don't need to generate an epg file every single time... only when a record in the epgData table is modified or created. at that point, we can query which epgs contain that specific channel and update only those epgs.

Extended explanation:

This is what i'm imagining for the handling of epg files. a client logs in and buys a provider pack, let's say for TPS. we will offer 3 tiers of provider packs, the botom tier will simply have the epg data in the appropriate time slot. no emojis, no channel icon, no description, no pre and post event helpful program entries, basically all the features stripped out. the middle tier will have some features, and the top tier will have all of the features. so essentially, for tps, we will have 3 epg files (1 for each tier). When a user buys, we'll say the top tier, they are issued a unique url - something like https://epgo.at/G7dK4r On our end, since they purchased the top tier for tps, when they visit that url, it will forward to a hidden (unguessable) top tier tps xml file. if someone else buys the top tier tps account, they're url will be https://epgo.at/k8VfX2 and it will point to the same hidden unguessable top tier tps xml file. This helps in a few ways... the random 6 character alpha-numeric string is what we use to control access. when it is created, it is stored with a termination date and other meta data. on termination day, the url simply quits resolving to the actual epg data file. My goal for features offered to top tier... we can allow them to customize that url string. So with all of this said, the system proposed above will have an epgData record for each monitored channel in the playlist. If we have our script run hourly, we perform a diff on the last file proccessed compared to this newly obtained file, if there are no actual differences, we don't process and a new epg file isn't created at all. we only create a new epg file if a record in the epgData table is created or modified, and that record ties back to the TPS provider (in this example)

Now, here's where it gets more complicated. For our top tier, or maybe we can offer a 4th 'customized' tier, that allows users to customize their features. We won't make this feature available at launch... it'll be added later. but essentially, the user will log in, they will purchase a Customized epg for a specific provider (TPS for example). Then, they will be shown all of our features with them all toggled on and the ability to either toggle them off, or adjust them (depending on the feature). with that said, we will essentially, at that time, have a customized epg file. If anyone else has chosen this exact same config, then both users' custom url can point to the same xml file, but if the confi is truly unique, we'll have to create a brand new xml file just for their customization/configuration. The main xml file will behave the same way as our top tier tps xml file with it having an unguessable url and the user's url pointing directly to it. 

Essentially, what i'm gettin at is, any time a record in epgData is created or modified, the system will need to find all playlists that contain that channel and recreate the epg at that time. these epg updates should be batched so that, if 3 epgData rows are updated, we aren't recreating the epg file 3 times. it can be recreated once with all 3 changes. 

along the same note, for our top tier offering, one of the features is that pre-live event program data should have details about the event. For instance, if an event starts at 7:30 pm, we should have program data for the morning slots that say something similar to "Lakers vs Rockets airing today at 7:30". This will be the program name for all program data up until the actual program which starts at 7:30 pm. The problem is... that "today at 7:30" section with regards to timezones. For the record, the bottom tier epg will simply have pre-live event program data as something like "no programming". The Mid tier will have something like "Lakers vs Rockets" while the top tier has "Lakers vs Rockets airing today at 7:30". The problem is, though, now we'll need an epg file for each timezone so that these pre-live-event programs will show appropriate time. The user will purchase a top-tier provider pack and specify their timezone. that way, their pre-live-event programs will show accurate information for that user. Basically, we'll have many actual epg files for users and each time a record in epgData is generated of updated, we'll need to regenerate the respective epg files.

I just thought of another thing. we have a feature somewhere that says when an account is near expiry, we will inject some "your account will expire soon" type of text in the epg data. is this still a good idea, and if so, we'll need additional epg files that have this text. 

I see us having a pretty large collection of different epg files considering we'll have 3 tiers, many timezone, expiring soon, expiring soon for each time zone, 10+ different providers, customizable feature packages, and eventually BYO iptv url. I see us growing a sizeable collection of epg files... all of which could start to take up a lot of space. let's discuss.'

another idea... epg files should not be created based off of date information (unless they are built based off of dates in accordance to the respective timezone for top tier packs).. it may be best to create them based on hours. so, if an epg file is generated now, it should either: A) take all entries within 24 hours in the past up to 48/72 hours in the future. B) evaulate the beginning of yesterday and the end of tomorrow based on the timezone of this specific epg file (only for top tier packs since bottom and middle tier won't have timezone options). 

We should keep a history table to log modifications of all tables. 

5. Incremental Processing Optimization

Goal: Avoid re-processing unchanged data

5.1 File Change Detection

Proposal: Store hash of processed files to detect changes

Workflow:

# Before processing
current_hash = hash_file("tps_playlist.m3u")
last_hash = db.get_last_processed_hash("tps", "playlist")

if current_hash == last_hash:
    print("No changes detected, skipping...")
    return
else:
    # Diff the files to find changes
    changes = diff_m3u_files(last_version, current_version)
    # Process only new/changed channels

Implementation Ideas: - Store file hashes in processed_files table - Track hash, provider, file_type, processed_at timestamp - Implement smart diffing for M3U files (line-by-line comparison) - Only process added/modified channels

5.2 Channel-Level Caching

Proposal: Skip channels that already have EPGData records

Workflow:

for channel in parsed_channels:
    channel_id = (channel.name, channel.provider)

    if epg_data_exists(channel_id):
        print(f"Skipping {channel.name} (already processed)")
        continue

    # Process new channel
    process_channel(channel)

Cache Invalidation Strategy: - Manual refresh: Force re-process specific channels - Time-based: Auto-refresh channels older than N days - Event-based: Refresh when EventDetails updated from API - Provider-based: Bulk refresh when provider changes detected

Discussion Points: - [ ] How long should channel data be cached? - [ ] When do we force a full refresh? - [ ] How to handle channels that legitimately change over time? - [ ] Performance implications of cache checks vs full reprocess


6. Handling Duplicate Channel Names

Problem: Multiple providers may have identically named channels

Example:

Provider A: "ESPN" → tvg-id="espn-provider-a"
Provider B: "ESPN" → tvg-id="espn-provider-b"

Proposed Solutions:

Option 1: Provider-Scoped Keys

unique_key = f"{provider}::{channel_name}"
# "TPS::ESPN" vs "NECRO::ESPN"

Option 2: Separate EPGData Records - One ChannelNames record per provider+name combo - One EPGData record per ChannelNames record - tvg-id includes provider identifier

Option 3: Shared EPGData with Provider List - One EPGData record, multiple ChannelNames point to it - Track which providers use this channel - Single tvg-id, providers reference same EPG data

Discussion Points: - [ ] Which option best fits our architecture? - [ ] How does this affect M3U generation? - [ ] What if same channel name has different content across providers? - [ ] Performance implications of each approach


7. Workflow Optimization Summary

Current Workflow (Simplified):

M3U → Parse → Match → Generate EPG (matched only)

Proposed Workflow:

M3U (Check hash) → Parse ALL → Store ParsedData →
Match with EventDetails → Generate EPGData (ALL) →
Output EPG (ALL) + Filtered M3U → Update hash

Key Improvements: 1. ✅ Parse everything, match what we can 2. ✅ Output EPG for all channels (not just matches) 3. ✅ Generate filtered M3U for easy testing 4. ✅ Rich descriptions for triage 5. ✅ Hash-based change detection 6. ✅ Channel-level caching 7. ✅ Clear data lineage (ChannelNames → ParsedData → EPGData)


8. Action Items for Wednesday Discussion

Come Prepared to Discuss: - [ ] Database choice (MySQL vs D1 vs PostgreSQL vs stay with D1) - [ ] Table schema validation (do proposed tables make sense?) - [ ] Parser enhancement priorities (what to tackle first?) - [ ] Output format validation (M3U + rich descriptions useful?) - [ ] Caching strategy (too aggressive? not enough?) - [ ] Duplicate channel name handling (which option?) - [ ] Migration plan (if changing database) - [ ] Timeline and effort estimates

Questions to Answer: - What's the minimum viable version of this redesign? - What can we implement incrementally vs big-bang migration? - Are there existing tools/libraries that solve parts of this? - How do we test the new architecture before full cutover? - What's our rollback plan if something goes wrong?


9. Open Questions & Considerations

Technical Questions: - How do we handle timezone conversions across providers? - Should we store raw channel strings separately from parsed data? - How do we version EPGData records (if channel content changes)? - What's our data retention policy (how long to keep old ParsedData)?

Product Questions: - Do we need multi-day EPG generation? (currently generates for one day) - Should we support manual overrides for bad matches? - Do we need a web UI for reviewing parse/match results? - What reports/dashboards would be useful?

Operational Questions: - How do we monitor EPG generation health? - What alerts do we need (parse failures, match rate drops, etc.)? - How do we handle API rate limits (TheSportsDB)? - What's our disaster recovery plan?


Next Steps: 1. Review this document before Wednesday 2. Prioritize discussion topics (we may not cover everything) 3. Identify any missing concerns/questions 4. Bring specific examples of current pain points 5. Be ready to make decisions and create action plan


🟠 HIGH (Important, Not Urgent)

[Fix 14 Failing Tests After Repository Restructure]

  • Status: NOT STARTED
  • Effort: 4-6 hours
  • Deadline: This week
  • Priority: HIGH - Clean up technical debt from restructure
  • Context: Repository restructure (PR #72) successfully merged with 98.2% test pass rate (770/784 tests passing). 14 tests are failing due to pre-existing functional bugs, not restructure issues.

Failing Tests Breakdown: 1. Cache Logic Bugs (7 failures in test_cross_provider_event_cache.py) - Cache not storing/retrieving events properly - Normalized name matching not working - Order-agnostic matching failing - Hit rate calculations incorrect

  1. Provider Orchestrator Mocking (5 failures in test_provider_orchestrator.py)
  2. ThreadPoolExecutor not being mocked correctly in parallel processing tests
  3. Test mocking strategy needs review

  4. API Enrichment (1 failure in test_api_enrichment.py)

  5. list_supported_leagues monkeypatch not working as expected
  6. Test logic issue with league candidate enumeration

  7. Enhanced Matching (1 failure in test_enhanced_matching.py)

  8. Requires Cloudflare API token (infrastructure dependency)
  9. Test needs mocking or environment setup

Next Steps: - [ ] Fix cache implementation in backend/epgoat/services/cross_provider_cache.py - [ ] Review and fix ThreadPoolExecutor mocking in orchestrator tests - [ ] Fix test_enrichment_attempts_all_league_candidates monkeypatch - [ ] Add Cloudflare API mocking for enhanced matching test - [ ] Run full test suite and verify 100% pass rate - [ ] Document test fixes in commit messages


[Ensure .github Directory Is Production-Ready]

  • Status: NOT STARTED
  • Effort: 2-3 hours
  • Deadline: This week
  • Priority: HIGH - CI/CD pipeline is critical infrastructure
  • Context: GitHub Actions workflows updated during restructure but need comprehensive review.

Tasks: - [ ] Review all workflow files (.github/workflows/) - test.yml - Updated but needs validation - Any other workflows that need updating? - [ ] Optimize CI/CD pipeline - Check for redundant steps - Ensure proper caching (pip cache, etc.) - Verify timeout values are appropriate - Review job dependencies and parallelization - [ ] Add missing workflows - Consider adding: security scanning, dependency updates, etc. - [ ] Test workflow triggers - Verify push/PR triggers work correctly - Test branch protection integration - [ ] Document CI/CD setup* - Update Documentation/08-Processes/CI-CD-Pipeline.md - Include workflow descriptions and maintenance instructions

Related Files: - .github/workflows/test.yml - Main test and lint workflow - Documentation/08-Processes/CI-CD-Pipeline.md - CI/CD documentation


[Intelligent Auto-Issue Creation for GitHub Actions Failures]

  • Status: NOT STARTED
  • Effort: 3-4 hours
  • Deadline: Before production launch
  • Priority: HIGH - Improve operational visibility for system failures
  • Context: Added 2025-11-07 after fixing provider onboarding workflow quoting bug

Goal: Automatically create GitHub issues for genuine system failures (not user errors) in GitHub Actions workflows to improve incident response.

Implementation Strategy: 1. Selective Issue Creation - Only create issues for: - Database connection failures (Supabase, D1) - API authentication failures (TheSportsDB, ESPN, Cloudflare) - Unexpected exceptions (Python tracebacks) - Infrastructure errors (R2 upload failures)

  1. Exclude User Input Errors - Do NOT create issues for:
  2. Argument parsing errors ("unrecognized arguments")
  3. Validation errors ("invalid choice")
  4. Empty/malformed M3U URLs
  5. Missing required fields

  6. Error Classification Logic: ```yaml

  7. name: Create Issue on System Failure if: failure() && !contains(github.event.inputs.*, 'test') uses: actions/github-script@v7 with: script: | const errorLog = await core.summary.stringify();

     // Classify error type
     const isUserError = errorLog.includes('unrecognized arguments') ||
                        errorLog.includes('invalid choice') ||
                        errorLog.includes('required:');
    
     // Only create issue for system errors
     if (!isUserError) {
       await github.rest.issues.create({
         owner: context.repo.owner,
         repo: context.repo.repo,
         title: `[AUTO] ${context.workflow} Failed`,
         body: `**Workflow**: ${context.workflow}\n**Run**: ${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}\n\n### Error\n\`\`\`\n${errorLog}\n\`\`\``,
         labels: ['bug', 'automated', context.workflow.toLowerCase()]
       });
     }
    

    ```

  8. Enhanced Error Messages - Add structured error output: ```yaml

  9. name: Handle Failure if: failure() run: | echo "::error title=Workflow Failed::Check logs above. Common issues: invalid credentials, network timeouts, or infrastructure errors." ```

  10. Deduplication Strategy:

  11. Search for existing open issues with same error signature
  12. Add comment to existing issue instead of creating duplicate
  13. Close auto-created issues when workflow succeeds again

Workflows to Instrument: - [ ] .github/workflows/onboard-provider.yml - Provider onboarding - [ ] .github/workflows/team-sync.yml - Team synchronization - [ ] .github/workflows/test.yml - CI/CD test pipeline - [ ] Any future automated workflows

Benefits: - ✅ Faster incident detection (no need to check workflow logs daily) - ✅ Reduced noise (only real system issues create tickets) - ✅ Clear audit trail of infrastructure problems - ✅ Better operational visibility for remote team

Alternatives Considered: - ❌ Create issues for ALL errors → Too much noise, unusable issue tracker - ❌ Only log to Slack → No audit trail, messages get lost - ✅ Selective creation + improved error messages → Best balance

Next Steps: - [ ] Implement error classification logic in onboard-provider.yml - [ ] Add issue deduplication check (search existing issues) - [ ] Test with intentional failures (bad credentials, etc.) - [ ] Roll out to team-sync.yml and test.yml - [ ] Document issue triage process for auto-created issues

Related Files: - .github/workflows/onboard-provider.yml - Fixed quoting bug, needs auto-issue logic - .github/workflows/team-sync.yml - Candidate for auto-issue creation - Documentation/08-Processes/CI-CD-Pipeline.md - Document auto-issue behavior


[Infrastructure Usage Monitoring & Alerting]

  • Status: NOT STARTED
  • Effort: 4-6 hours
  • Deadline: Before production launch
  • Priority: HIGH - Prevent unexpected charges from exceeding free tier limits
  • Context: Supabase and R2 have free tier limits. Need safeguards to alert before we approach these limits.

Services to Monitor: - Supabase PostgreSQL: - Database size (500MB free tier limit) - Bandwidth usage (2GB/month free tier limit) - API requests (if applicable) - Cloudflare R2: - Storage size (10GB free tier limit) - Class A operations (1M/month uploads/PUT/LIST - free tier limit) - Class B operations (10M/month downloads/GET - free tier limit)

Alert Thresholds: - 70% threshold (Warning): Slack/Discord notification - 85% threshold (High Alert): Slack/Discord + dashboard banner - 95% threshold (Critical): Slack/Discord + dashboard banner + daily summary reports

Notification Channels: 1. Slack/Discord Webhook: Immediate alerts sent to team channel 2. Dashboard Warning Banner: Visible warning in admin interface when thresholds exceeded 3. Daily Summary Report: Email with current usage stats (sent when >70%) 4. Weekly Summary Report: Comprehensive usage trends and projections

Implementation Details: - Automated Script: Python script (cron job) that checks usage every 6-12 hours - Query Supabase metrics via SQL: SELECT pg_database_size('postgres') - Query R2 usage via boto3 API - Calculate percentage of free tier limit - Send notifications based on thresholds - Dashboard Widget: Real-time usage display in admin interface - Shows current usage vs limits for each service - Color-coded status (green/yellow/orange/red) - Trend graph (usage over time)

Related Documentation: - Supabase Setup - Free tier limits and monitoring queries - R2 Setup - R2 pricing and usage monitoring

Next Steps: - [ ] Create Python monitoring script with API integrations - [ ] Set up Slack/Discord webhook for alerts - [ ] Implement dashboard widget with real-time metrics - [ ] Configure cron job for automated checks - [ ] Test all notification channels - [ ] Document monitoring setup and troubleshooting


🟠 HIGH (This Week)

[LLM-Based Channel Detection Verification for Provider Onboarding]

  • Status: NOT STARTED (Planning Phase)
  • Effort: 6-8 hours (design + implementation + testing)
  • Deadline: Before production launch
  • Priority: HIGH - Improves data quality and reduces manual validation overhead
  • Context: Added 2025-11-08 - Current pattern-based channel detection needs validation layer
  • Branch: claude/llm-verify-channel-detection-011CUvg1XXjvEGc6tNBTdjWW

Current Problem: The provider onboarding process (backend/epgoat/services/provider_onboarding_service.py) uses template-based pattern discovery to identify which channels need monitoring. The algorithm: 1. Groups channels by PREFIX (text before first digit) 2. Extracts templates using digit-stripping (e.g., "NCAAF ~% : ") 3. Filters by frequency threshold (≥5 matches) 4. Writes parseable channels directly tochannel_names` table

The current detection is intentionally loose (better to include too many than miss valid channels), but this means: - Pattern logic errors: Channels that matched the PREFIX+digit pattern but don't actually follow numbered series logic - False groupings: Channels grouped together that shouldn't be (e.g., one-off channels that happen to have numbers) - Unnecessary database bloat from storing irrelevant channels - Wasted processing during EPG generation

Key Insight: Channels don't need to be sports-specific (e.g., "Paramount+ 01 :", "Live Event 01 |" are VALID). We need to verify that detected channels actually follow the numbered series pattern logic, not filter by content type.

Proposed Solution: Add an LLM pattern logic verification AFTER pattern discovery but BEFORE database write, then create GitHub issue with findings:

# Current flow:
patterns = self._discover_patterns(live_channels)
parseable_channels = [ch for ch in live_channels if self._is_parseable(ch['name'])]
# Write directly to database ❌ (may include pattern logic errors)

# Proposed flow:
patterns = self._discover_patterns(live_channels)
parseable_channels = [ch for ch in live_channels if self._is_parseable(ch['name'])]

# NEW: LLM pattern logic verification
verification_result = self._verify_pattern_logic_with_llm(parseable_channels, patterns)

# Apply 80% confidence threshold
channels_to_write = verification_result.get_high_confidence_channels(threshold=0.80)
flagged_channels = verification_result.get_low_confidence_channels(threshold=0.80)

# Write high-confidence channels ✅ (pattern logic validated)
self._save_channels_to_database(channels_to_write)

# Create GitHub issue for manual review (PER PROVIDER)
self._create_verification_issue(
    provider_name=provider_name,
    verification_result=verification_result,
    flagged_channels=flagged_channels
)

Implementation Details:

  1. Create new service: backend/epgoat/services/channel_pattern_verifier.py ```python class ChannelPatternVerifier: """LLM-based verification of channel pattern logic."""

    def verify_pattern_logic( self, channels: List[Dict[str, Any]], patterns: List[Dict[str, Any]], ) -> PatternVerificationResult: """ Verify that detected channels follow numbered series pattern logic.

       Args:
           channels: List of parseable channels from pattern discovery
           patterns: Discovered patterns with templates
    
       Returns:
           PatternVerificationResult with:
           - verified: Channels that follow pattern logic (confidence >= 80%)
           - flagged: Channels that may not follow pattern logic (confidence < 80%)
           - verification_details: Per-channel confidence, reasoning, pattern match
           - stats: Verification counts by confidence level
       """
    

    ```

  2. LLM Prompt Strategy (Pattern Logic Verification): ``` You are verifying PATTERN LOGIC for an IPTV channel detection algorithm.

These channels were detected because they match a numbered series pattern: PREFIX + NUMBER + SEPARATOR (e.g., "NBA 01 :", "Paramount+ 05 |", "Live Event 12 - ")

Your job: Verify that each channel actually follows numbered series logic.

Discovered patterns:

Channels to verify (batch of {N}):

For each channel, respond with: 1. follows_pattern_logic: true/false (does this look like a numbered series?) 2. confidence: 0-100% (how confident you are in your assessment) 3. matched_pattern: Which pattern template this matches (or "none") 4. reason: Brief explanation

VALID numbered series (should have HIGH confidence): - "NBA 01 : Lakers vs Celtics" (clearly part of NBA 01-99 series) - "Paramount+ 05 : Movie Title" (clearly part of Paramount+ 01-99 series) - "Live Event 12 | Soccer Match" (clearly part of Live Event series) - "PPV 03 - Boxing Tonight" (clearly part of PPV series)

INVALID pattern matches (should have LOW confidence): - "ABC 20/20" (one-off show, not a numbered series) - "Channel 7 News" (station identifier, not a series) - "60 Minutes" (show title with number, not a series)

Note: Content type doesn't matter (sports, movies, events all valid). What matters: Does this follow numbered series logic?

Format as JSON array. ```

  1. Batch Processing & Caching:
  2. Process in batches of 50-100 channels (balance cost vs latency)
  3. Cache LLM responses to avoid re-verification
  4. Store verification results in new table: channel_verification_log

  5. GitHub Issue Creation (PER PROVIDER): ```python def _create_verification_issue( self, provider_name: str, provider_id: int, verification_result: PatternVerificationResult, high_confidence_channels: List[Dict[str, Any]], low_confidence_channels: List[Dict[str, Any]] ) -> str: """ Create GitHub issue for manual review of verification results.

    Issue contains: - Summary stats (total channels, verified %, flagged %) - LOW confidence section (top): Channels <80% with SQL queries for approval * Sorted by confidence DESCENDING (lowest confidence first - most likely false positives) - HIGH confidence section (bottom, collapsed): Channels ≥80% already in DB * Sorted by confidence ASCENDING (lowest confidence first - borderline cases) - LLM reasoning for each channel - Copy-paste SQL queries for easy manual approval

    Returns: issue_url: URL to created GitHub issue """ ```

SQL Query Generation: Each low-confidence channel includes a ready-to-run INSERT query: python def _generate_approval_sql(self, provider_id: int, channel: Dict[str, Any]) -> str: """Generate SQL query to approve a flagged channel.""" return f""" INSERT INTO channel_names (provider_id, channel_name, channel_name_normalized, tvg_id, tvg_logo, group_title, stream_url) VALUES ( {provider_id}, '{channel['name'].replace("'", "''")}', '{channel['name'].lower().strip().replace("'", "''")}', '{channel.get('tvg_id', '')}', '{channel.get('tvg_logo', '')}', '{channel.get('group_title', '')}', '{channel.get('url', '')}' ) ON CONFLICT (provider_id, channel_name_normalized) DO UPDATE SET last_seen = CURRENT_TIMESTAMP; """

Issue Template: ```markdown ## Provider Onboarding Verification: {provider_name}

Automated pattern detection completed with LLM verification.

### Summary - Total channels detected: {total} - High confidence (≥80%): {verified_count} ({verified_pct}%) - Auto-saved to database - Low confidence (<80%): {flagged_count} ({flagged_pct}%) - Manual review required - LLM model: {model_name} - Total cost: ${cost}


## Low Confidence Channels (Manual Review Required)

These channels scored below 80% confidence. Sorted by confidence (lowest first) - most likely false positives at the top. Review each channel and run the SQL query if valid.

### Channel: "ABC 20/20" - Confidence: 45% - Pattern Match: None - LLM Reasoning: One-off show title, not a numbered series. The "20/20" refers to the show name, not a channel series number. - Recommendation: ❌ Reject (likely false positive)

✅ SQL to approve this channel (if valid) ```sql -- Run this query to add channel to database INSERT INTO channel_names (provider_id, channel_name, channel_name_normalized, tvg_id, tvg_logo, group_title, stream_url) VALUES ( {provider_id}, 'ABC 20/20', 'abc 20/20', '{tvg_id}', '{tvg_logo}', '{group_title}', '{stream_url}' ) ON CONFLICT (provider_id, channel_name_normalized) DO UPDATE SET last_seen = CURRENT_TIMESTAMP; ```

### Channel: "Channel 7 News" - Confidence: 52% - Pattern Match: None - LLM Reasoning: Station identifier, not a numbered series pattern. The "7" is part of the station name, not a series number. - Recommendation: ❌ Reject (likely false positive)

✅ SQL to approve this channel (if valid) ```sql INSERT INTO channel_names (provider_id, channel_name, channel_name_normalized, tvg_id, tvg_logo, group_title, stream_url) VALUES ( {provider_id}, 'Channel 7 News', 'channel 7 news', '{tvg_id}', '{tvg_logo}', '{group_title}', '{stream_url}' ) ON CONFLICT (provider_id, channel_name_normalized) DO UPDATE SET last_seen = CURRENT_TIMESTAMP; ```

### Channel: "Live Event 12 | Soccer Match" - Confidence: 75% - Pattern Match: "Live Event ~`% |" - LLM Reasoning: Appears to follow numbered series pattern, but confidence slightly below threshold due to generic prefix "Live Event". - Recommendation: ⚠️ Review (may be valid)

✅ SQL to approve this channel (if valid) ```sql INSERT INTO channel_names (provider_id, channel_name, channel_name_normalized, tvg_id, tvg_logo, group_title, stream_url) VALUES ( {provider_id}, 'Live Event 12 | Soccer Match', 'live event 12 | soccer match', '{tvg_id}', '{tvg_logo}', '{group_title}', '{stream_url}' ) ON CONFLICT (provider_id, channel_name_normalized) DO UPDATE SET last_seen = CURRENT_TIMESTAMP; ```

## High Confidence Channels (Auto-Saved) ✅

These {verified_count} channels scored ≥80% confidence and were automatically saved to the database. Sorted by confidence (lowest first) - borderline cases at the top for review.

Show all high confidence channels | Channel Name | Confidence | Pattern Match | LLM Reasoning | |--------------|------------|---------------|---------------| | Live Event 08 - Championship | 80% | Live Event ~`% - | Numbered series pattern, borderline confidence | | PPV 03 - Boxing Tonight | 82% | PPV ~`% - | Clear numbered series pattern for PPV events | | Paramount+ 05 : Movie Title | 85% | Paramount+ ~`% : | Clear numbered series pattern for streaming service channels | | NFL 12 :: Sunday Game | 92% | NFL ~`% :: | Clear numbered series pattern for NFL channels | | NBA 01 : Lakers vs Celtics | 98% | NBA ~`% : | Clear numbered series pattern, part of NBA 01-99 series | | ... | ... | ... | ... |

## Actions Required

  • [ ] Review low confidence channels above
  • [ ] For valid channels: Copy and run the SQL query provided
  • [ ] For invalid channels: Close this section (no action needed)
  • [ ] If pattern discovery needs adjustment: Create separate issue

### Raw Verification Data

Full verification results JSON ```json {verification_result_json} ```


Auto-generated by provider onboarding workflow Run ID: {github_run_id} Provider ID: {provider_id} ```

  1. Database Schema Addition: sql CREATE TABLE channel_verification_log ( id INTEGER PRIMARY KEY, provider_id INTEGER, channel_name TEXT, pattern_matched TEXT, follows_pattern_logic BOOLEAN, llm_confidence FLOAT, -- 0.0-1.0 (e.g., 0.85 for 85%) llm_reasoning TEXT, llm_model TEXT, -- e.g., 'claude-haiku-3-5' llm_cost_cents FLOAT, verified_at TIMESTAMP, github_issue_url TEXT, -- Link to review issue FOREIGN KEY (provider_id) REFERENCES providers(id) );

Additional column in providers table: sql ALTER TABLE providers ADD COLUMN last_verification_issue_url TEXT;

Key Decision Points:

  1. Confidence Threshold: ✅ DECIDED: 80%
  2. Apply threshold: Only write channels where llm_confidence >= 80%
  3. Channels below 80% flagged in GitHub issue for manual review
  4. Balances automation with safety (high-confidence auto-saved, uncertain flagged)

  5. Which Anthropic Model?DECIDED: Claude Haiku 3.5

  6. Cost: $0.25/MTok input, $1.25/MTok output (~$0.01-0.02 per provider)
  7. Fast (sub-second), sufficient for pattern logic validation
  8. Can switch to Sonnet 3.5 later if accuracy becomes an issue

  9. GitHub Issue Creation: ✅ DECIDED: Always Create Issue Per Provider

  10. Every onboarding run creates one issue for that provider
  11. Issue contains flagged channels (confidence < 80%) for manual review
  12. High-confidence channels (≥80%) auto-saved, no review needed
  13. Issue URL stored in providers.last_verification_issue_url
  14. Issue labels: provider-channel-prefixes-review and provider:{provider_name} (e.g., provider:tps, provider:necro)

  15. Verification Scope: ✅ DECIDED: ALL Channels

  16. Verify ALL parseable channels identified by pattern discovery
  17. No sampling - complete verification for maximum accuracy
  18. Batched API calls to manage costs and performance

  19. When to Run: ✅ DECIDED: Automatic During Onboarding

  20. Runs automatically as part of provider onboarding workflow
  21. No manual trigger required
  22. Integrated into onboarding pipeline (pattern discovery → LLM verification → DB write)
  23. Only during initial onboarding (not on pattern changes or re-runs)

  24. Dry-Run Behavior: ✅ DECIDED: Create GitHub Issues in Dry-Run

  25. Dry-run mode WILL create GitHub issues for review
  26. Allows reviewing verification results before committing to database
  27. Issue will note that this was a dry-run in the title or description

  28. Cost Considerations:

  29. Example: 1,000 channels × 50 tokens avg = 50K tokens
  30. Haiku cost: ~$0.01-0.02 per provider onboarding
  31. Sonnet cost: ~$0.15-0.20 per provider onboarding
  32. Annual cost (10 providers, quarterly re-verification): <$10 (Haiku) or ~$80 (Sonnet)

Benefits (Pattern Logic Validation): - ✅ Primary: Validates that detected channels actually follow numbered series pattern logic - ✅ Filters out pattern logic errors (e.g., "ABC 20/20" one-off shows, "Channel 7" station IDs) - ✅ Reduces database bloat by removing false groupings - ✅ Improves EPG generation efficiency (fewer irrelevant channels to process) - ✅ Automatic GitHub issue creation for manual review of flagged channels - ✅ Copy-paste SQL queries for easy manual approval of low-confidence channels - ✅ Complete visibility: All channels (high + low confidence) listed in GitHub issue - ✅ Provides audit trail with LLM reasoning for each verification - ✅ Self-documenting (LLM explains pattern logic assessment) - ✅ Supports non-sports content (Paramount+, Live Events, PPV, etc.) as valid patterns - ✅ Minimal manual effort: Just copy SQL query and run if channel is valid

Risks & Mitigations: - ⚠️ Risk: LLM may flag a valid numbered series as low-confidence - Impact: LOW - Channel gets flagged in GitHub issue for manual review (you can approve it) - Mitigation: 80% threshold allows some uncertainty while auto-saving high-confidence - Mitigation: Full verification data logged to database for analysis

  • ⚠️ Risk: Cost accumulation with large providers (1000+ parseable channels)
  • Impact: VERY LOW - Even with 1000 channels, cost is ~$0.02 per onboarding (Haiku)
  • Mitigation: Caching prevents re-verification of same channels
  • Mitigation: Batch processing optimizes API calls

  • ⚠️ Risk: LLM approves channels that don't follow pattern logic (false negatives)

  • Impact: LOW - Same outcome as current system (status quo)
  • Mitigation: Track approval accuracy over time, adjust prompt if needed
  • Mitigation: GitHub issues provide manual backstop

Next Steps: - [ ] Review and approve this pattern logic validation design - [ ] Decide on Anthropic model (Haiku 3.5 recommended for cost) - [ ] Create channel_pattern_verifier.py service - [ ] Add database migration for channel_verification_log table + provider column - [ ] Implement GitHub issue creation via gh CLI - [ ] Integrate into provider_onboarding_service.py (call before DB write) - [ ] Test with existing provider (measure verification accuracy) - [ ] Measure cost per onboarding run - [ ] Test GitHub issue creation with sample flagged channels - [ ] Update provider onboarding guide and document verification workflow

Related Files: - backend/epgoat/services/provider_onboarding_service.py (integration point at line 686-704) - backend/epgoat/services/team_name_resolution_service.py (similar LLM pattern to follow) - backend/epgoat/services/channel_pattern_verifier.py (NEW - to be created) - backend/epgoat/infrastructure/backend/epgoat/infrastructure/database/migrations/ (new migration needed) - .github/workflows/onboard-provider.yml (GitHub Actions integration for gh CLI)

Design Complete: All decisions finalized, ready for implementation.


[Update EPG-Matching-Pipeline.md Architecture Documentation]

  • Status: NOT STARTED
  • Effort: 6-8 hours
  • Deadline: End of week (2025-11-08)
  • Priority: HIGH - Heavily referenced, currently outdated after Phase 2 and team resolution integration
  • Context: Added 2025-11-07 after team resolution integration complete

Current Problem: - Documentation describes old architecture (pre-Phase 2) - Missing handler-based architecture (7 handlers) - Missing team resolution preprocessing step - Missing enrichment pipeline flow - References obsolete code patterns

Required Updates: - [ ] Rewrite architecture overview (2 hours) - Document 7-handler chain (EnhancedMatchCache → EventDetailsCache → LocalDatabase → RegexMatcher → CrossProviderCache → API → Fallback) - Document preprocessing phase (team parsing → team resolution → sport detection → time extraction → league inference) - Add handler priority ordering explanation

  • [ ] Document team resolution integration (1 hour)
  • LLM-based canonical name resolution
  • Self-improving alias cache
  • Cost optimization strategy
  • Integration point in preprocessing phase

  • [ ] Update data flow diagrams (1-2 hours)

  • M3U → Parser → EnrichmentContext → Preprocessing → Handler Chain → XMLTV
  • Add Mermaid.js diagrams for clarity

  • [ ] Document enrichment context (1 hour)

  • EnrichmentContext data structure
  • How data flows through handlers
  • Handler decision logic

  • [ ] Add troubleshooting section (1 hour)

  • Common handler failures
  • Cache debugging
  • Team resolution issues

  • [ ] Update code references (1 hour)

  • Fix all file paths and line numbers
  • Add links to actual implementation
  • Remove references to deprecated code

Related Files: - Documentation/03-Architecture/EPG-Matching-Pipeline.md (needs major rewrite) - Documentation/08-Projects/Archive/2025-Q4/Team-Resolution-Integration-Complete.md (reference for recent changes)


[Phase 2: Core Documentation Guides]

  • Status: NOT STARTED
  • Effort: 8-12 hours (2-3 hours per guide)
  • Deadline: End of week (2025-11-08)
  • Details: DOCUMENTATION-AUDIT-2025-11-02.md
  • Priority: HIGH - These guides are heavily referenced in 00-START-HERE.md

Work Items: - [ ] Write Development-Setup.md (2-3 hours) - Full dev environment setup guide - Prerequisites, installation, verification - IDE configuration - Stub exists with outline: Documentation/04-Guides/Development-Setup.md

  • [ ] Write Testing-Guide.md (2-3 hours)
  • How to write and run tests
  • Testing pyramid, AAA pattern
  • Running specific tests, coverage
  • NEW FILE - No stub yet

  • [ ] Write Database/Schema.md (2-3 hours)

  • Complete database schema documentation
  • All tables, columns, relationships
  • ER diagrams (Mermaid.js)
  • Stub exists with outline: Documentation/05-Reference/Database/Schema.md

  • [ ] Complete EPG-Generation.md (2-3 hours)

  • Comprehensive EPG generation guide
  • Step-by-step walkthrough
  • Common issues, troubleshooting
  • Stub exists with outline: Documentation/04-Guides/EPG-Generation.md

  • [ ] Complete Pattern-Matching.md (1-2 hours)

  • Finish the pattern matching guide
  • Add examples, troubleshooting
  • File exists but incomplete: Documentation/04-Guides/Pattern-Matching.md

🟡 MEDIUM (This Sprint)

[Update System-Overview.md with Team Resolution]

  • Status: NOT STARTED
  • Effort: 1 hour
  • Deadline: End of sprint (2025-11-15)
  • Priority: MEDIUM - System overview should reflect latest architecture
  • Context: Added 2025-11-07 after team resolution integration complete

Required Updates: - [ ] Add team resolution service (30 minutes) - Document TeamNameResolutionService component - Add to system components diagram - Explain self-improving behavior

  • [ ] Update enrichment pipeline section (30 minutes)
  • Document preprocessing phase
  • Team resolution integration point
  • Update data flow diagram

Related Files: - Documentation/03-Architecture/System-Overview.md (needs team resolution section) - Documentation/08-Projects/Archive/2025-Q4/Team-Resolution-Integration-Complete.md (reference)


[Update Database Schema Documentation with Migration 017]

  • Status: NOT STARTED
  • Effort: 30 minutes
  • Deadline: End of sprint (2025-11-15)
  • Priority: MEDIUM - Keep migration index up to date
  • Context: Added 2025-11-07 after migration 017 completed

Required Updates: - [ ] Add Migration 017 to migration index (15 minutes) - Document LLM metadata columns in team_aliases - Document team_discovery_cache table removal - Migration date: 2025-11-07

  • [ ] Update team_aliases table schema (15 minutes)
  • Add llm_confidence, llm_cost_cents, llm_tokens_used, channel_context columns
  • Update table diagram in Schema.md

Related Files: - Documentation/05-Reference/Database/Schema.md (needs migration 017) - backend/epgoat/infrastructure/backend/epgoat/infrastructure/database/migrations/017_simplify_team_discovery.sql (reference)


[Phase 3: Architecture Decision Records]

  • Status: NOT STARTED
  • Effort: 10-15 hours
  • Deadline: End of sprint (2025-11-15)
  • Details: DOCUMENTATION-AUDIT-2025-11-02.md
  • Priority: MEDIUM - Important for architectural understanding

Work Items: - [ ] Write ADR-002: EPG Matching Architecture (3 hours) - Document the 6-stage matching pipeline decision - Context, decision, consequences, alternatives - Stub exists: Documentation/06-Decisions/002-EPG-Matching-Architecture.md

  • [ ] Write ADR-003: Phase 2 Service Architecture (3 hours)
  • Document Phase 2 architectural decisions
  • Service layer, caching strategy
  • Use STUB-TEMPLATE.md as starting point

  • [ ] Write ADR-004: Multi-Stage Regex Matcher (2 hours)

  • Document regex matching approach
  • Why multi-stage, performance considerations
  • Use STUB-TEMPLATE.md as starting point

  • [ ] Write ADR-005: Parallel Provider Processing (2 hours)

  • Document multi-provider architecture
  • Parallelization strategy, trade-offs
  • Use STUB-TEMPLATE.md as starting point

  • [ ] Complete Database/ Reference Folder (2-3 hours)

  • Supabase-Setup.md - Database provisioning guide
  • Credentials.md - Credential management
  • Migrations.md - Migration workflow
  • All stubs exist in 05-Reference/Database/

  • [ ] Write Process Documentation (2-3 hours)

  • Code-Review-Process.md - How to review code
  • Release-Process.md - How to do releases
  • NEW FILES - No stubs yet

⚪ LOW (Backlog)

[Phase 4: Complete All Reference Documentation]

Work Items: - [ ] Complete all API reference docs (6 hours) - [ ] Complete all Database reference docs (4 hours) - [ ] Add code examples to Engineering-02-Standards/Examples/ (5 hours) - [ ] Write advanced standards (API, Performance, Monitoring) (5 hours)

[Phase 5: Enhancements]

Work Items: - [ ] Add visual diagrams (Mermaid.js) - [ ] Create runbooks - [ ] Video tutorials - [ ] Interactive examples


✅ COMPLETED (Last 7 Days)

[LLM-Based Channel Pattern Verification for Provider Onboarding]

  • Status: ✅ DONE (2025-11-09)
  • Completed By: Claude Code (with user collaboration)
  • Effort: 6 hours (design + implementation + testing + documentation + refactoring)
  • Branch: claude/llm-verify-channel-detection-011CUvg1XXjvEGc6tNBTdjWW

What Was Done: - ✅ Integrated LLM pattern verification directly into provider_onboarding_service.py - ✅ Implemented _verify_pattern_with_llm() using Claude Haiku 3.5 - ✅ Created Version 1 prompt achieving 88.9% accuracy (tested with 9 channels) - ✅ Added helper methods: _build_verification_prompt(), _calculate_pattern_confidence() - ✅ Refactored to meet <50 line engineering standards (split 102-line function into 3 functions) - ✅ Integrated into pattern discovery workflow with 80% confidence threshold - ✅ Added LLM verification metadata storage (llm_verified, llm_confidence, llm_reason) - ✅ Documented feature in Provider-Onboarding-via-GitHub-Actions.md with examples - ✅ Updated living document provider-onboarding-service-design.md - ✅ All functions comply with Python standards (type hints, docstrings, naming)

Implementation Approach (Simplified vs Original Plan): - Implemented: Integrated verification directly in onboarding service - Original Plan: Separate channel_pattern_verifier.py service + GitHub issue creation - Decision: Simpler, more maintainable approach that accomplishes core goal - Trade-off: No GitHub issues for manual review (patterns auto-filtered at 80% threshold)

Verification Results: - Cost: ~$0.0008 per pattern (6 channels sampled) - Model: claude-3-5-haiku-20241022 - Accuracy: 88.9% (8/9 correct on test set) - False positives rejected: "ABC 20/20", "Channel 7 News", "60 Minutes" - Valid patterns accepted: BIG10+, Bundesliga, DAZN CA, ESPN+, NBA

Impact: - Reduces database bloat by filtering false positives - Improves EPG generation efficiency (fewer irrelevant channels) - Self-documenting (LLM provides reasoning for each verification) - Supports non-sports content (Paramount+, Live Events, PPV validated as correct patterns) - Minimal cost (~$0.04 for typical 50-pattern provider)

Commits: - fcc4541 - feat(onboarding): add LLM verification for channel pattern detection - 2ef8b7d - docs: document LLM verification in provider onboarding - 08b3bed - refactor: split _verify_pattern_with_llm to meet 50-line standard


[Test Fixture Organization - Nov 2025 Channel Names]

  • Status: ✅ DONE (2025-11-05)
  • Completed By: Claude Code (CTO mode)
  • Effort: 30 minutes
  • Original Request: Move 2025-11-01 Example Channel Names.csv to appropriate location and document it

What Was Done: - ✅ Moved CSV file from project root to backend/epgoat/tests/fixtures/ - ✅ Renamed file with proper convention: 2025-11-01-channel-names-1386.csv - ✅ Created comprehensive fixtures README.md with: - Documentation for all test fixtures - Detailed description of Nov 1, 2025 dataset (1,386 channels) - Usage examples for automated and manual testing - Guidelines for adding new fixtures - Maintenance and versioning guidelines - ✅ Preserved important metadata: date (Nov 1, 2025), channel count (1,386)

Impact: - Test data now properly organized and version-controlled - Clear documentation for using fixture in tests - Established conventions for future test fixtures - Date-specific data clearly marked for appropriate use


[Documentation Reorganization & Naming Convention]

  • Status: ✅ DONE (2025-11-05)
  • Completed By: Claude Code (CTO mode)
  • Effort: 2 hours
  • Original Request: Reorganize Documentation folder - Standards and Work-In-Progress to root level

What Was Done: - ✅ Implemented consistent NN-Title-Case-With-Hyphens naming convention for ALL directories - ✅ Moved Standards → 02-Standards/ (root level, numbered by importance) - ✅ Moved Work-In-Progress → 01-Work-In-Progress/ (root level, highest priority) - ✅ Renumbered all directories by access frequency (01-11) - ✅ Created comprehensive README.md for all 11 root-level directories - ✅ Updated CLAUDE.md with new paths - ✅ Updated all skill files (maintain-documentation, engineering-standards, check-work-inbox) - ✅ Documented naming convention in 09-Meta/Documentation-Standards.md - ✅ Added naming validation rules to maintain-documentation skill - ✅ Updated 150+ file references across codebase - ✅ Preserved git history for all moves (used git mv)

Impact: - Consistent, discoverable directory structure - Most important directories listed first (01, 02) - Convention documented and enforced via skills - Zero broken links, all references updated


[Phase 1: Fix Broken References]

What Was Done: - ✅ Created comprehensive CTO-level audit (400+ lines) - ✅ Created stub files for top 5 most-referenced docs - ✅ Added READMEs to 3 empty folders - ✅ Renamed PATTERNS_GUIDE.md → Pattern-Matching.md - ✅ All stubs include workarounds and planned content

Impact: Documentation now usable with clear WIP markers instead of broken.


Archive Instructions

After 1 week in "Completed" section: 1. Move detailed file (audit/checklist) to Documentation/10-Projects/Archive/2024-Q4/ 2. Remove from this TODO-BACKLOG.md 3. Update any references in other docs

For temporary checklists: Just delete (no historical value)


Quick Stats

Total Pending Work: ~44-64 hours (including Architecture Redesign implementation) - 🔴 Critical: 5 items (~160 hours total - includes 4-week Architecture Redesign) - 🟠 High: 5 items (8-14 hours) ← Updated 2025-11-09 (LLM verification completed) - 🟡 Medium: 3 items (12-17 hours) - ⚪ Low: 2 items (20-25 hours)

Completion Target: - Phase 2 (High): End of this week - Phase 3 (Medium): End of this sprint - Phase 4 (Low): Next sprint


Tips

💡 Start with High priority items - These unblock other work 💡 Do 2-3 hour chunks - Each guide is one focused session 💡 Use the stubs - They have outlines and workarounds 💡 Update this file - Mark items done as you complete them 💡 Don't feel overwhelmed - This is 2-3 sprints of steady work


Questions? See README.md for how the Work Inbox system works.

Full Audit Details: DOCUMENTATION-AUDIT-2025-11-02.md