Skip to content

Alpha.1 — multi-source Guided Setup, web-link enrollment, guide bindings, and evidence-driven guide validation #175

Open

Description

@Jumpstile

Parent gates

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:

  1. structural validation;
  2. station/channel plausibility within the bound playlist context;
  3. compare overlapping enrolled guides;
  4. compare supported programme/event data against approved online evidence sources;
  5. detect gaps, stale entries, conflicts, duplicates, and suspicious assignments;
  6. correct/enrich only with sufficient evidence;
  7. preserve provenance/confidence;
  8. 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:

  1. source-set v2 durable records;
  2. multi-M3U/multi-XMLTV enrollment;
  3. public HTTPS source enrollment;
  4. explicit guide bindings;
  5. headless source-set candidate generation;
  6. per-source refresh/restart persistence;
  7. browser Guided Setup controls;
  8. cross-guide comparison/validation;
  9. approved online evidence adapters;
  10. 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

  1. Jumpstile commented on Sep 21, 2026

    @Jumpstile
    OwnerAuthor

    Implementation gate cleared. Exact main f70e73c1e967ef4f8bb9a31a9055c2b7c991cb8c passed post-merge run 35601880534 with secret-scan PASS and quality-gates PASS. #175 may now begin from this exact base.

  2. Jumpstile commented on Sep 21, 2026

    @Jumpstile
    OwnerAuthor

    REQUEST_CHANGES — two source-set authority blockers remain despite green CI.

    1. Multi-playlist guide ownership is still inferred implicitly.

    At current head 0f130f568c961f0d53ba404be45f490f4f650455, Write-ChannelForgeSourceSet auto-creates bindings whenever guides exist and no bindings were supplied. With multiple playlists this binds every guide to every playlist while setting AppliesToAll=false.

    That violates the product contract:

    • single playlist: automatic guide binding is allowed;
    • multiple playlists: the relationship must be explicit;
    • ALL/shared must be an explicit choice;
    • absence of a binding must never silently mean “all playlists.”

    Required correction:

    • if exactly one playlist exists and guides are supplied with no bindings, auto-bind each guide to that one playlist;
    • if more than one playlist exists and guides are supplied with no explicit bindings, either preserve guides as explicitly unbound/actionable or fail closed with a source-set/binding-required result. Do not guess.
    • add a regression proving 2 playlists + 1 guide + no binding does not silently associate that guide with both playlists.
    • add a regression proving explicit AppliesToAll=true is the only ALL/shared representation.
    1. Source and binding identity uniqueness is not enforced.

    SourceId is derived from Kind + 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 same BindingId more than once.

    Required correction:

    • reject duplicate playlist SourceIds;
    • reject duplicate guide SourceIds;
    • reject a SourceId appearing in both collections if the identity model permits collision;
    • reject duplicate BindingIds / duplicate effective guide-binding relationships;
    • add focused tests for all duplicate-ID cases.

    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:

    • rerun focused source enrollment/binding tests;
    • full Pester;
    • parser/PSSA/config schemas/Prettier/Markdown/diff;
    • hosted exact-head secret-scan and quality-gates.

    Do not merge PR #178 until these are cleared.

  3. Jumpstile commented on Sep 25, 2026

    @Jumpstile
    OwnerAuthor

    Product-owner disposition for the single-playlist binding default:

    • If exactly one playlist exists and a newly added guide has no prior/saved binding decision, ChannelForge should auto-bind that guide to the sole playlist. This is the beginner-friendly default already specified in Issue Alpha.1 — multi-source Guided Setup, web-link enrollment, guide bindings, and evidence-driven guide validation #175.
    • If the user explicitly clears/unbinds that guide in the browser, that explicit unbound decision must be preserved. A later proposal/review must not silently re-bind it merely because only one playlist exists.
    • Missing/omitted binding data from legacy/headless input is not the same as an explicit browser unbound choice.
    • With multiple playlists, omitted binding remains unbound/actionable unless a saved unambiguous binding applies. Never infer ALL.
    • Explicit ALL remains explicit only through AppliesToAll=true.

    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.

  4. Jumpstile commented on Sep 28, 2026

    @Jumpstile
    OwnerAuthor

    Alpha.1 / PR #182 Gate 0 update — 2026-09-27

    PR #182 merged to main.

    • Final PR head: b750d92b028507a5c29c139fc82de2e7ea033b8d
    • Merge SHA / current remote main: c765d78b7ff8665a34f149b66aa90bc4919e676a
    • Exact-head PR CI: SUCCESS
    • Full direct Owner Smoke: 46/46 PASS
    • Package SHA-256: 41729c55fa2a1826b9337a16bba1ac121b636360cc9d71f897f978673581abd5
    • Post-merge main CI: run 36368861201, currently in progress

    The smoke test bed caught and repaired:

    • stale contradictory accepted-state UI cards after restart;
    • hardcoded shell Not configured state;
    • occupied-port start safety;
    • alternate-port start deleting live server PID ownership.

    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.

  5. Jumpstile commented on Sep 28, 2026

    @Jumpstile
    OwnerAuthor

    Gate 0 complete

    Post-merge main CI for merge SHA c765d78b7ff8665a34f149b66aa90bc4919e676a completed successfully.

    • secret-scan: PASS
    • quality-gates: PASS
    • workflow run: 36368861201

    Combined 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.

  6. Jumpstile commented on Oct 20, 2026

    @Jumpstile
    OwnerAuthor

    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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions