v0.18.2-0042: fix #1015 daily slot rollover dedup (maintainer-integrated) - #1020
Merged
Merged
Conversation
…lot rollover Event providers reuse a fixed pool of slot names and roll the fixture and the airing over every day, so yesterday's channel for a slot and today's stream for the same slot share every template word. token_set_ratio scored the pair at 0.86-0.99 — above the default 0.80 — queued the stream as a pending merge, and deferred the channel creation. When the whole pool rolled over, the run created nothing and the group stayed on yesterday's fixtures until orphan cleanup happened to delete their candidate channels. - dedup_matcher: a pair whose two stated airings (the date/time run in the name) disagree is dropped before scoring. Stripping the run instead would leave two character-identical names scoring 1.00, so the run is treated as a signal, not noise. A name that states no airing scores byte-for-byte as before, and the 0.60 floor and operator threshold are untouched. - executor: the pending-merge candidate list no longer includes the channel the stream is already attached to (the pair scores 1.00 by construction). - executor/engine/tasks: a deferred create names its blocking pending_merges row, the run summary counts the deferred streams and lists the rows, and the follow-on assign_epg reports the deferral instead of the bare "No channel context for assign_epg" that operators read as an EPG fault. The queue-lifecycle asks (auto-expiring a pending row whose candidate channel is gone, sticky per-pair dismissal) are deliberately out of scope here: ADR-008 §D4, migration 0014 and a recorded PO decision all specify today's behaviour, so changing them is an ADR amendment for the PO. The addendum says so explicitly. Tests: airing-gate unit cases (rollover does not queue; identical names still do), candidate-scope cases, the rollover integration scenario through _execute_create_channel, deferral-reason surfacing, merge-id exposure on both the insert and the §D5 collision branch, and the run-summary contract for deferred streams. Verified by reverting the gate: the rollover tests fail with the reported 0.86-0.99 queueing behaviour and pass with it.
…rting (#1015) 1. airing_key accepts only valid airing tokens: a real month name or abbreviation, a day in 1-31, a real clock (12-hour with a meridiem, 24-hour otherwise), complete tokens (a day cannot start inside a longer number; a clock cannot continue into more digits). The name is scanned for the FIRST VALID run, so a false prefix cannot hide a real trailing airing. "Sports 24 Hour 09:30", "Channel 250 News 09:30" and "Sky Sports F1 Live 20:00" state no airing and score as before. 2. Zones are supported literal labels (GMT, UTC, IST, BST, CET, EST, ...), bare or with a numeric offset, compared as written; GMT vs IST differ. A non-zone suffix after the clock (HD2, UHD, RAW) is not a zone and leaves the key unchanged. 3. The single "Completed with Warnings" notification for an unattended failed-action run carries the deferral diagnosis and the blocking row ids (task_engine message branch for auto_creation + metadata extras), built from the same phrase as the engine log and the task summary. 4. Units are distinct: pending_merges_added counts deferred create actions, pending_merge_stream_count counts distinct streams, and pending_merge_ids lists distinct rows (deduplicated in the executor and in the engine aggregation). describe_pending_merge_deferral renders all three on every surface. 5. A deferral explanation is scoped to one create attempt: the next create attempt for the same stream clears it, so a later failure in another group is not misattributed to the earlier pending merge. 6. The regex has no unanchored whitespace scan (bounded \s{1,3} gaps, a lookbehind day boundary and a lookahead clock boundary); the source comment states the actual runtime property. 7. Group/name eligibility is applied before stream membership is inspected, so non-candidate channels' memberships are never traversed. Tests: airing-key validation table and the reviewer's counterexamples through find_candidate; bare and offset zones; non-zone suffixes; false prefix with a real trailing airing; regex structure plus a bounded timing check on padded input; executor membership-traversal proof, attached exclusion after the reorder, distinct stream/action/row counts on a §D5 collision, attribution superseded by a later failed create; engine aggregation through _process_streams (distinct rows/streams, JSON-safe result); task details carry the note and stream count; the task-engine warning message and metadata carry the deferral and rows; a run without deferrals keeps the generic warning. test_same_airing_still_scores_fuzzily now uses genuinely different normalized names and asserts a non-exact accepted score. ADR-008 addendum and changelog aligned with the corrected grammar, zone policy, counter units, notification surface and regex runtime; dry-run visibility is called out as a maintainer decision. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MGuX7qVpTp99bzYZXgLJMm
…1016 review Strict-delta review on PR #1016 asked for retained regressions that cross the real boundaries rather than mocked ones, plus an explicit disposition of the dry-run visibility ask. - New tests/integration/test_gh1015_deferral_end_to_end.py drives a real pending_merges table, the real ActionExecutor + BD-F hook, the real ChannelPipelineEngine.run_pipeline, the real ChannelPipelineTask post-refresh path and the real TaskEngine completion notification, with only Dispatcharr and the notification sink doubled. It asserts the emitted "Completed with Warnings" payload names the deferral and the persisted PendingMerge row ids on the fresh-insert refresh and on the next refresh (every row a D5 collision), that two same-named streams from two providers share one row while the counters keep actions (2) / streams (2) / rows (1) apart in the engine result, task details and warning metadata, that no channel is created for a deferred stream, and that its assign_epg failure in the persisted execution log names the deferral and the row. A control run with nothing deferred carries no deferral wording or ids. - test_channel_pipeline_executor_dedup_hook.py gains the false-prefix / trailing-airing rollover through enqueue and execution: the next-day fixture creates and queues nothing; the same trailing airing with a different fixture still queues, against the persisted row. - ADR-008 addendum and CHANGELOG record the maintainer decision: dry-run pending-merge visibility is owned by #1018 and this change does not claim preview/live parity. - Rebased onto origin/dev (#1006, #1008, #1017 landed); build stays 0038. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ror warning (#1015) Review round 3 on PR #1016: a capped run with failed actions emits the task's own "Capped, with errors" notification and suppresses the task engine's generic warning, so a capped, failed, deferred run named neither Pending Merges nor its blocking rows in the one warning it sent. - tasks/channel_pipeline.py computes describe_pending_merge_deferral before the cap block; the cap/error message appends the same bounded phrase plus the Pending Merges pointer, and the notification metadata carries pending_merges_added, pending_merge_stream_count and pending_merge_ids. - tests/tasks/test_gh1015_deferred_merge_visibility.py: a capped + failed + deferred result through _run_post_refresh_pipeline emits exactly one warning, titled "Capped, with errors", carrying the phrase, the rows and the metadata, with the engine warning suppressed; a capped run with no deferrals keeps the plain cap warning and no metadata. - tests/integration/test_gh1015_deferral_end_to_end.py: a real refresh with max_auto_created_channels_per_run=1, one deferred stream and two creatable ones ends capped with one create, persists one PendingMerge row, and the single emitted warning names that row id in its message and metadata. - CHANGELOG and ADR-008 addendum name the combined cap/error surface. - RED check: dropping the append fails both new tests on the phrase. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
| from __future__ import annotations | ||
|
|
||
| import json | ||
| from datetime import datetime |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This replacement PR supersedes #1016 only because maintainer edits are disabled on the contributor branch. It preserves and credits the original work by @lukeeexd from #1016 at exact head
622b1363e78293687e5da903928adf4d8787d819, merged without rebasing onto currentdevatb3169ca9421bed7d6cc72a8449fc0b017dc117f0.Closes #1015 for the daily-rollover bug. Dry-run pending-merge visibility remains explicitly deferred to #1018, matching the maintainer disposition recorded on #1016; this PR does not claim preview/live parity.
Conflict resolution
describe_pending_merge_deferral, distinct action/stream/row counters, persisted row IDs, capped/failed/deferred single-warning behavior, end-to-end queue-to-warning evidence, and the full accepted matcher/executor matrix.dev.0.18.2-0042; ordered the changelog as 0042, 0041, then 0040 without dropping either prior entry.Verification
git diff --check: passed.ECM_GATE_COMPLETEecm-gate-o44geeax.tests/integration/test_gh1015_deferral_end_to_end.py, engine, executor, task-warning, replay/logo, matcher, run-summary, and version tests: 803 passed, 0 failed;ECM_GATE_COMPLETEecm-gate-u0g89zbg.scripts/backend-gate.sh: 14,247 passed, 4 skipped, 2 deselected, 83.36% coverage;ECM_GATE_COMPLETEecm-gate-ui6dq5jw.Original PR #1016 is intentionally left open and unchanged.