Repository navigation
Description
Parent gates
- First Usable Alpha release-readiness gate #164 First Usable Alpha release-readiness gate
- Autonomous Operations — scheduled refresh, multi-guide learning, source drift detection, and zero-touch maintenance #35 Autonomous Operations
- EPG Acquisition and Merge — multi-lineup identity, validation, provenance, and deterministic XMLTV #40 EPG Acquisition and Merge
- AED-compatible event pattern intelligence and automatic guide inference #121 AED-compatible event pattern intelligence
- Product-wide intent-fit code audit and standing implementation gate #141 Intent-fit gate
- UI architecture requirement: web-first local UI, Docker or Windows server install #150 Web-first local UI
Starting point
PR #174 merged to main at:
e42abf6d0f3e6ebb677a51c93d789b995253ff23
PR #174 delivered the Windows portable package/install/update/uninstall surface. This issue owns the next Alpha.1 source-input and guide-quality slice.
Product outcome
ChannelForge Guided Setup must support a durable source set:
- one-or-more M3U playlists
- zero-or-more XMLTV guides
- each supported source may be:
- local file
- supported public HTTPS web link
- guides may be bound explicitly to:
- one playlist
- multiple selected playlists
- all playlists/shared
- guide data is evidence, not unquestioned truth:
- compare guides
- validate against approved online evidence sources
- detect conflicts/gaps
- fill only well-supported gaps
- preserve provenance/confidence
- never fabricate programme data
No-guide remains valid.
Existing capability audit
Current engine:
- multi-M3U engine support: YES
- multi-XMLTV engine support: YES
- remote public HTTPS M3U/XMLTV configured-source support: YES
- deterministic M3U merge authority:
Merge-ChannelForgeLineup.ps1 - deterministic XMLTV merge authority:
Merge-ChannelForgeXmltvProgrammes.ps1 - evidence model:
GuideEvidenceRecord - readiness aggregation:
Get-ChannelForgeGuideReadiness - LKG accepted-state preservation: YES
Current browser/durable enrollment:
- browser multiple M3Us: NO
- browser multiple XMLTV guides: NO
- browser XMLTV web link: NO
- durable source-set enrollment: NO
- explicit guide-to-M3U binding: NO
- online guide validation/enrichment: NO
- gap filling: NO
Configured engine support for public HTTPS XMLTV exists, but browser Guided Setup currently only submits one local M3U and optional local XMLTV bytes.
Credential-bearing/tokenized URLs are currently not safely persisted by browser enrollment and must remain unsupported until a secure persistence contract exists.
Source-set v2 model
Implement a durable server-owned source-set authority.
Playlist record
Each playlist record should include at least:
- stable server-owned source ID
- safe display label
- source kind:
- managed file
- public HTTPS URL
- enabled/present state
- content hash or cache metadata
- provenance
- refresh state
- deterministic ordering/priority field if needed
Guide record
Each guide record should include at least:
- stable server-owned source ID
- safe display label
- source kind:
- managed file
- public HTTPS URL
- enabled/present state
- content hash or cache metadata
- provenance
- refresh state
- deterministic ordering/priority field if needed
Guide binding
Durable explicit relationship:
- guide ID
- playlist IDs:
- explicit list
- ALL/shared
- enabled
- binding revision/version
Binding changes must contribute to candidate identity/hash.
Source enumeration order must never imply guide ownership.
Beginner Guided Setup
Normal choices:
Playlists
- M3U playlist file
- M3U playlist web link
- Add another playlist
Guides
- XMLTV guide file
- XMLTV guide web link
- Add another guide
- No guide
For each guide, show:
Use this guide for:
- Playlist 1
- Playlist 2
- ...
- All playlists
Use safe friendly labels where possible.
Do not expose server IDs, hashes, internal paths, cache keys, or secret-bearing URLs.
Defaults
If exactly one playlist exists:
- bind newly added guide automatically to it.
If multiple playlists exist:
- reuse a saved unambiguous binding where appropriate;
- otherwise ask once;
- never infer from source order.
Multi-source behavior
Support at minimum:
- 2+ M3Us, no guide
- 1 M3U + 2+ guides
- 2+ M3Us + 1 guide
- 2+ M3Us + 2+ guides
- mixed local-file + public-HTTPS source sets
Users can:
- add a source
- remove a source
- replace a source
- refresh all
- inspect per-source status
Do not force config-file editing for normal multi-source use.
M3U aggregation
Parse each playlist independently and preserve source provenance.
Handle deterministically:
- duplicate channels
- same
tvg-id - aliases/renames
- duplicate stream URLs
- conflicting groups
- conflicting metadata
- source ordering changes
Safe exact consolidation may happen automatically.
Material ambiguity must remain review-blocked.
Do not silently prefer one playlist merely because it is enumerated first.
XMLTV aggregation
Keep guides source-scoped during acquisition/validation.
Honor guide-to-M3U bindings before applying guide evidence.
For multiple guides bound to one playlist:
- compare coverage/freshness
- merge exact duplicates
- preserve contributors/provenance
- surface conflicting alternatives as review/evidence
- use explicit precedence/evidence policy, not enumeration order
A guide bound only to Playlist A must not enrich Playlist B.
Guide-to-M3U binding semantics
- one playlist may have multiple guides;
- one guide may serve multiple playlists;
- ALL/shared is explicit, not implicit;
- replacing a guide preserves bindings by default;
- refreshing a guide preserves bindings;
- removing a playlist removes only that playlist relationship;
- a guide still used elsewhere remains;
- a guide with no remaining binding becomes actionable/unbound;
- never silently retarget an orphaned guide.
Public HTTPS source enrollment
Use the existing bounded transport/trust machinery.
Do not create a second downloader.
Support only URLs allowed by current source URL policy.
Fail closed for:
- non-HTTPS
- localhost/private/internal hosts
- embedded credentials
- unsafe redirects
- malformed data
- oversized content
- zero-length content
- acquisition failure
Tokenized/credential-bearing URLs remain unsupported until secure persistence exists.
The UI must state that limitation clearly.
Durable restart/refresh
The complete source set and bindings survive:
- restart
- application upgrade
- refresh
Per-source refresh status must be visible.
Example:
- Playlist 1 — Up to date
- Playlist 2 — Changes found
- Guide 1 — Up to date
- Guide 2 — Source unavailable
Aggregate beginner message:
Needs attention — one guide could not be refreshed. Your accepted lineup is still safe.
A failed source must not erase healthy sources or accepted last-known-good state.
Changed inputs produce a candidate/review path; they do not silently mutate accepted state.
Evidence-driven guide validation
XMLTV is an evidence source, not automatically canonical truth.
For enrolled guides:
- structural validation;
- station/channel plausibility within the bound playlist context;
- compare overlapping enrolled guides;
- compare supported programme/event data against approved online evidence sources;
- detect gaps, stale entries, conflicts, duplicates, and suspicious assignments;
- correct/enrich only with sufficient evidence;
- preserve provenance/confidence;
- never fabricate programme data.
Evidence classes
Evaluate/record evidence class such as:
- official broadcaster/network schedule
- official league/event organizer
- provider XMLTV
- configured trusted XMLTV
- trusted secondary schedule source
- heuristic/inferred evidence
Do not treat all sources equally.
No secondary website becomes an unqualified truth source.
Programme enrichment / gap filling
Where corroboration is strong enough, ChannelForge may fill/correct:
- missing programme blocks
- title/subtitle
- descriptions
- start/stop times
- teams
- league
- event type
- episode/season metadata
- categories
- venue/location
- postponed/rescheduled/cancelled status
Weak inference alone must not fill a gap.
If evidence conflicts or is insufficient:
- preserve LKG where appropriate;
- mark review-needed;
- do not invent.
Provenance
For every enriched/corrected programme, preserve:
- original guide source(s)
- corroborating source(s)
- fetch/freshness time
- original value
- resulting value
- reason
- evidence/confidence state
- automatic vs review-required disposition
Provenance/confidence must survive restart/refresh.
Online validation adapters
Use an approved source-adapter model rather than arbitrary uncontrolled scraping.
Each adapter must have:
- source identity
- evidence/trust class
- bounded fetch behavior
- rate-limit/backoff expectations
- validation status
- fetch timestamp
- provenance
- failure semantics
Prefer official sources where available.
Sports/event sources should integrate with #121 and the same evidence model.
Acceptance boundary
Do not let guide validation/enrichment bypass immutable acceptance.
High-confidence enrichment may be automatic only where policy explicitly permits.
Material uncertainty remains review-required.
Accepted guide/lineup output remains last-known-good until explicit promotion where review matters.
Headless-first implementation order
Implement in this order:
- source-set v2 durable records;
- multi-M3U/multi-XMLTV enrollment;
- public HTTPS source enrollment;
- explicit guide bindings;
- headless source-set candidate generation;
- per-source refresh/restart persistence;
- browser Guided Setup controls;
- cross-guide comparison/validation;
- approved online evidence adapters;
- enrichment/gap-fill after provenance/confidence/correction-history contracts are explicit.
Do not start with UI-only arrays over the old single-source authority.
Required tests
At minimum:
Multi-source
- 2 M3Us, no guide
- 1 M3U + 2 guides
- 2 M3Us + 2 guides
- mixed file/HTTPS sources
- duplicate/overlapping channels
- overlapping XMLTV stations/programmes
- enumeration-order determinism
Bindings
- Guide A -> M3U 1 only
- Guide B -> M3U 2 only
- Guide C -> both/all
- one playlist + multiple guides
- restart persistence
- refresh persistence
- replacement preserves binding
- playlist removal does not silently rebind
- orphaned guide becomes actionable
Refresh/LKG
- one failed source while others remain healthy
- partial refresh failure preserves accepted output
- changed source creates candidate only
- no silent acceptance
Remote URLs
- valid public HTTPS XMLTV/M3U
- unsupported scheme
- private/localhost
- embedded credentials
- unsafe redirect
- malformed/oversize/empty
- redaction/no URL leakage
Guide validation
- two guides agree
- two guides conflict
- official source corroborates one
- missing programme filled from strong corroboration
- weak source does not fill
- online validator unavailable
- stale schedule
- start-time correction
- title correction
- rescheduled/cancelled sports event
- provenance retained
- confidence retained
- binding prevents cross-playlist contamination
- deterministic enrichment
Documentation and screenshots
Update beginner docs and README with real implementation screenshots showing:
- multiple playlists
- multiple guides
- file vs web-link source choices
- guide-to-playlist assignment
- per-source refresh state
- guide validation statuses:
- Guide checked
- Confirmed
- Enriched
- Needs attention
No fake shipped screenshots.
Technical provenance details may live under advanced/details surfaces.
Explicit non-goals
- no credential/token vault design in this issue unless required to safely support credential-bearing URLs;
- no arbitrary web scraping framework;
- no silent publication of uncertain guide corrections;
- no accepted-state redesign;
- no second refresh engine;
- no Docker-specific deployment work;
- no 1.0 compatibility matrix.
Done when
- durable source-set v2 is authoritative;
- multiple M3U/XMLTV sources work end-to-end;
- public HTTPS enrollment works safely;
- explicit guide bindings work;
- restart and refresh preserve all relationships;
- browser workflow exposes the model simply;
- per-source status works;
- guide validation/enrichment slice has explicit evidence/provenance contracts and shipped implementation for the bounded Alpha.1 scope;
- all tests/docs/screenshots are synchronized;
- exact-head hosted checks are green;
- no release/tag until First Usable Alpha release-readiness gate #164 is satisfied.
Release impact
This issue is release-gating for Alpha.1.
PR #174 packaging is complete, but #164 remains open until this source-set/web-link/binding/guide-quality work is completed or explicitly re-scoped by the product owner.
Activity
Jumpstile commentedon Sep 21, 2026
Implementation gate cleared. Exact main
f70e73c1e967ef4f8bb9a31a9055c2b7c991cb8cpassed post-merge run35601880534with secret-scan PASS and quality-gates PASS. #175 may now begin from this exact base.Jumpstile commentedon Sep 21, 2026
REQUEST_CHANGES — two source-set authority blockers remain despite green CI.
At current head
0f130f568c961f0d53ba404be45f490f4f650455,Write-ChannelForgeSourceSetauto-creates bindings whenever guides exist and no bindings were supplied. With multiple playlists this binds every guide to every playlist while settingAppliesToAll=false.That violates the product contract:
Required correction:
AppliesToAll=trueis the only ALL/shared representation.SourceIdis derived fromKind + SourceKind + SourceKey. Two descriptors with the same stable key can therefore produce duplicate source records with the same ID. Likewise duplicate binding inputs can produce the sameBindingIdmore than once.Required correction:
Also verify the persisted/read path fails closed if a hand-edited v2 record contains duplicate source or binding IDs.
Do not widen into browser UI, remote acquisition, guide validation/enrichment, or refresh redesign.
After correction:
Do not merge PR #178 until these are cleared.
Jumpstile commentedon Sep 25, 2026
Product-owner disposition for the single-playlist binding default:
PR #182 should be adjusted narrowly to implement and test this distinction before owner smoke. No change to journal/v2, immutable promotion, recovery, or acceptance auditability is authorized by this disposition.
Jumpstile commentedon Sep 28, 2026
Alpha.1 / PR #182 Gate 0 update — 2026-09-27
PR #182 merged to
main.b750d92b028507a5c29c139fc82de2e7ea033b8dc765d78b7ff8665a34f149b66aa90bc4919e676a41729c55fa2a1826b9337a16bba1ac121b636360cc9d71f897f978673581abd536368861201, currently in progressThe smoke test bed caught and repaired:
Not configuredstate;Do not close/reclassify #175 solely from this comment until post-merge main CI completes and the remaining issue checklist is reconciled against what PR #182 actually delivered.
Jumpstile commentedon Sep 28, 2026
Gate 0 complete
Post-merge
mainCI for merge SHAc765d78b7ff8665a34f149b66aa90bc4919e676acompleted successfully.36368861201Combined with the exact-head 46/46 Owner Smoke and successful PR-head CI, the PR #182 / Alpha.1 owner-smoke gate is now fully closed.
Current forward work continues on PR #199 One Guide remediation; no rollback or additional Gate 0 work is required.
Jumpstile commentedon Oct 20, 2026
Source-scoped XMLTV refresh regression evidence — 2026-10-20
Observed 12:47 UTC. Dispatcharr development commit 37f0273b2d9b5d33cbc568e4f2746c3dd303da0b, October 19 23:08:38 UTC: Dispatcharr/Dispatcharr@37f0273 . Not stable v0.32.0 or an installed-fix claim.
Verified source behavior: the XMLTV importer enumerated existing TVG IDs for one EPG source, but advanced its pagination cursor using rows with those IDs from every source. A higher row ID in a different source could skip remaining records; ignored conflicting inserts then left names/icons stale. The fix uses one source-filtered query. Added tests refresh source A when source B shares its TVG ID and verify source B remains unchanged; tests were inspected, not executed here.
Why/recommendation: shared tvg-id text is not global identity. Adopt regression coverage for two guides sharing an ID, disjoint metadata and interleaved database IDs; require source scope in lookup, cursor and update operations while honoring explicit guide-to-playlist bindings. Stale names/artwork from an importer defect must not become provider rename/removal evidence or learned aliases. This is an inferred ChannelForge acceptance case, not a diagnosed ChannelForge bug.
Classification Adopt regression fixture / Study implementation / Compatibility impact; medium priority, high identity-integrity test value. Scope existing multi-guide binding and evidence validation under #175; related #40/#27/#31/#35. Confidence high for inspected patch; runtime applicability unverified. Status NEW after exact-SHA search and 14-day canonical reconciliation; #175 verified as the specific guide-binding owner. No automatic repair, source setting, installation or publication change.