2025-09-04 - 2026-09-04
Overview
23 Releases published by 2 users
Published
v26.15.0
Published
v26.14.0
Published
v26.13.0
Published
v26.12.0
Published
v26.11.0
v26.11.0
Published
v26.10.0
v26.10.0
Published
v26.9.0
v26.9.0
Published
v26.8.0
v26.8.0
Published
v26.7.0
v26.7.0
Published
blazor-final
Published
v26.6.0
v26.6.0 — ChicoryTV SPA parity release
Published
v26.5.0
v26.5.0
Published
v26.4.0
v26.4.0
Published
v26.3.1
v26.3.1
Published
v26.3.0
Published
v26.2.0
Published
v26.1.1
Published
v26.1.0
Published
v25.9.0
Published
v25.8.0
Published
v25.7.1
Published
v25.7.0
Published
v25.6.0
385 Pull requests merged by 2 users
Merged
#906 fix(876): sweep session narrative out of hooks, workflows, scripts, tests and code comments; grow the detector to the process corpus
Merged
#905 fix(869,893): re-establish the 1.25.4-dated CI claims on 1.27.1, and settle the page_statuses asymmetry from source
Merged
#903 fix(891): a sourced path is code, so every hook resolves it from its own tree
Merged
#902 fix(855): two glob dialects cannot be canonicalised into one, so model one shape and refuse the rest
Merged
#899 fix(887): the image build builds the SPA and does not test it
Merged
#898 docs(release): record the v26.15.0 release notes
Merged
#897 fix(858,859): a rule the classifier cannot read is not a rule that matches nothing
Merged
#896 fix(870): an empty timeline page is not exhaustion — the walk reads to its cap
Merged
#892 fix(880): an absent recurrence array means unrestricted, an explicit [] is rejected
Merged
#890 fix(849): the verdict gate replaces every unknown state, and proves the clauses that claim to
Merged
#889 fix(845): the verdict writer checks that the gate will honour what it just posted
Merged
#888 docs(853): workflow_dispatch can't be ref-restricted at 1.27.1 — and restricting it would close nothing
Merged
#884 fix(836): never pass --depth to a checkout that may already be complete
Merged
#883 fix(820): derive where Complete<T> is APPLIED, not just what it means
Merged
#882 fix(812): classify the narrative sites by who-benefits; keep the detector's reach
Merged
#879 fix(823,824): a scheduling NULL collection reads as UNRESTRICTED and is guarded at both read sites; the Elastic indexer gets its own mutation proof
Merged
#875 fix(819): derive the SPA page-size guard population from the git index
Merged
#874 fix(809,822): isolate the suite from the production hook-fire log by construction
Merged
#873 fix(803,664): fence the HEAD alias on the PR timeline's pull_push count
Merged
#872 fix(786,789): workflows declare their own per-job metadata; guard populations derive from it
Merged
#871 docs(796): verification code is code under test — and the proof it was claiming an exemption from
Merged
#868 fix(763): page both /statuses/{sha} reads to a validated terminator
Merged
#867 docs(747): re-verify the Gitea 1.25.4-pinned CI claims on 1.27.1, and measure the merge-gate semantics that were source-attested
Merged
#866 probe(747c): DO NOT MERGE
Merged
#864 probe(747a): DO NOT MERGE
Merged
#863 probe(747): absent required status context — DO NOT MERGE
Merged
#862 docs(781,799): re-measure the tooling audit from a derived population, and adopt serena
Merged
#861 fix(787): derive the dropped-step guard's scope, and reconcile its snapshot against the server
Merged
#860 fix(748): declare permissions: on all six workflows, and prove the declaration binds
Merged
#857 fix(744,835): ci-image.yml publishes from main only; guard persist-credentials with no exemption
Merged
#850 fix(742): inherit an h10 verdict only from an allow-listed reviewer
Merged
#847 feat(735): bound the numeric FFmpeg profile fields with a 422, and expose readrate pacing
Merged
#846 fix(788): one declarative H10 verdict vocabulary, derived by both sides
Merged
#843 feat(732): On Now / Next gets a background box, and is on by default
Merged
#842 fix(746): drop the persisted checkout credential; unmask the base-ref fetches
Merged
#841 feat(734): field-level progressive disclosure — shared FieldHelp trigger + panel
Merged
#838 docs(755): ersatztv owns the fork code, media-management owns channel operations
Merged
#834 docs(708): record the live route-2 reproduction against PR #761
Merged
#833 fix(690,758): count the same query a paged handler pages
Merged
#831 fix(721,740): align Auto-Tune proposal rows on a grid; guard AddItemsDialog's async searches
Merged
#827 fix(807): SPA full-replace bodies are built as Complete<T>, with a derived guard over droppable request members
Merged
#826 fix(701): guard SongMetadata's nullable primitive collections at the read site
Merged
#825 fix(772,792): name the missing toolchain image; stop a refusal leaving a verdict comment
Merged
#818 fix(806): guard populations over FILES derive from the git index, not a filesystem walk
Merged
#817 docs: a cancelled job reads as failure where a monitor actually looks
Merged
#815 feat(790): execute every MUTATION grade instead of asserting it
Merged
#814 fix(780): reconcile the ruff gate with #784, merged in parallel
Merged
#813 feat(780): commit a ruff config and enforce it in CI
Merged
#811 feat(784): a doc records the end state — generalize the no-session-narrative rule
Merged
#810 test(785): mutation proofs for the three unproven ranked guards
Merged
#808 feat(779): test the deny path at the production config value, and derive full-replace field lists
Merged
#802 feat(778): name the check-and-use race, and verify the protection the merge gate rests on
Merged
#801 feat(794): witness a fix's test failing BEFORE the fix, and check the claim in CI
Merged
#800 docs(781): re-measure §5.3 from a derived population — the zeros split four ways
Merged
#795 feat(776): every hook reports that it fired, and the report is measured
Merged
#798 fix: the BOM guard was fail-open wherever xxd is not installed
Merged
#793 fix(777): repair both broken LSPs, and name the surface a subagent can actually reach
Merged
#762 chore(deps): update dependency scriban.signed to 7.2.6
Merged
#791 feat(774,775): one rule for guard populations, one for guard proofs — both enforced
Merged
#782 docs(773): root-cause the recurring defect shapes across the full closed-issue corpus
Merged
#770 fix(767): gate the release path on the delimiter ban with a prerequisite job
Merged
#769 docs(720): name all three Komodo stacks and the label-based resolution rule
Merged
#768 fix(756): extend the dropped-step guard to docker-build.yml's required jobs, where a drop is fail-OPEN
Merged
#764 fix(751): a stray expression delimiter in a COMMENT killed the verdict gate — plus the two nil-slice twins and a dead-code guard it hid
Merged
#760 fix(754,757): declare graphicsElementIds + padToNearestMinute, and pin every MCP tool to its OpenAPI contract
Merged
#749 fix(743): make review-verdict/h10 unskippable — disable direct push to main + admin force-merge; fix(719) tag-only push
Merged
#745 fix(697): scope CI's registry credential so head-resolved workflows cannot forge review-verdict/h10
Merged
#741 fix(685): AddItemsDialog resolves by search instead of windowing the whole media-library type
Merged
#739 docs(release): record the v26.14.0 release notes
Merged
#725 fix(674,688): cross-check decision frontmatter against PyYAML; split the ceiling calibration claim
Merged
#737 fix(726): let a lagging realtime input catch up so a sparse bitmap-subtitle stream can't pin it below realtime
Merged
#723 fix(706,707,711): fence the review-verdict write on the timeline retarget count
Merged
#717 chore(deps): update dependency cliwrap to 3.10.4
Merged
#718 chore(deps): update dependency jetbrains.resharper.globaltools to 2025.3.5
Merged
#716 docs(release): record the v26.13.0 release notes
Merged
#714 chore(deps): batch three Renovate patch bumps (supersedes #679, #680, #681)
Merged
#712 chore: ignore .codex/, and stop shipping a plaintext credential in docs
Merged
#710 docs(698): correct the Renovate auto-pass rule in CLAUDE.md
Merged
#705 fix(698): bind the base, constrain the bot exemption by content, re-derive unattributable successes
Merged
#699 fix(672): trigger the verdict gate on pull_request_target scoped to main
Merged
#700 fix(691): guard the nullable SongMetadata.Artists/AlbumArtists at their read sites
Merged
#692 fix(671): resolve rerun-collection selections through one shared include chain
Merged
#687 fix(668): reach accented facet values via a registered Unicode fold on SQLite
Merged
#686 fix(684): key the pageSize guard registry on identity, not source position
Merged
#683 docs(649): narrow the base-ref headline to what the checkout actually binds
Merged
#673 test(649): cover the review-verdict status read and the bot-path guards
Merged
#682 docs: permit subagents explicitly, and make claiming an issue a check rather than a label
Merged
#676 feat(578): artist typeahead covers music-video and song credits; album_artist stops 404ing
Merged
#675 fix(650): two at-cap list truncations, and a completeness guard that keys on the defect
Merged
#678 feat(651): library-browse pickers resolve by search, not a 100-row window
Merged
#666 fix(649): point the ENFORCED review-verdict gate at the shared PR-file enumeration
Merged
#667 fix(632): bind a review verdict to its BASE branch, not only to its head sha
Merged
#658 fix(648): an explicit jq version contract + one shared PR-file enumeration
Merged
#659 docs(ersatztv skill): record the #510 no-logo-no-bug policy and deco seeding recipe
Merged
#657 docs(505): retire the stale "do NOT set QSV on jazz" rule in the ersatztv skill
Merged
#655 fix(510): one watermark resolver for all four attachment points
Merged
#656 fix(644): stop seven SPA list loads truncating silently — one shared pager, bounded media pickers
Merged
#654 fix(505): tonemap QSV HDR through OpenCL — vpp_qsv=tonemap is a silent no-op
Merged
#642 fix(620): signal corpus size per RECORD; the aggregate becomes an untresholded trend
Merged
#637 fix(631): run scripts/tests in CI as its own job, not inside the flake-covered decisions-guard
Merged
#641 fix(621): make an unparseable decision record loud instead of silently invisible
Merged
#646 fix(633): document the 0-based paging contract on the OpenAPI parameters
Merged
#645 fix(634): page the rerun-collection picker to completeness
Merged
#636 fix(629): close six false-opens in the H10 verdict grammar, and give it tests
Merged
#639 fix(617): make the cross-repo skills real symlinks and reconcile the ersatztv skill
Merged
#635 fix(616): paging is 0-based — correct the MCP contract, fix a live 1-based SPA caller, un-cap two MCP tools
Merged
#630 fix(622): bind H10 merge consent to the reviewed sha via a required commit status
Merged
#613 fix(491): unique index on LibraryFolder(LibraryPathId, PathHash) + tolerate concurrent insert
Merged
#626 [THROWAWAY] probe(622) fix
Merged
#625 [THROWAWAY] probe(622) nofix
Merged
#624 [THROWAWAY] probe(622): commit pushed AFTER scheduling
Merged
#623 [THROWAWAY — DO NOT MERGE] probe(622): does a MISSING required status block auto-merge?
Merged
#619 feat(610): split the decision corpus into one YAML-frontmatter file per record
Merged
#618 fix(609): the decisions rationale-edit marker is a git trailer, not a bare substring
Merged
#607 fix(496): per-library server identity for music videos — itemId diff + soft trash
Merged
#612 feat(484): suppress the media-server sweep on projection failures; reject the ratio threshold
Merged
#611 fix(503): map WatermarkLocation.MiddleCenter to a centered overlay position
Merged
#605 feat(603): adopt OKF's optional stale-after and Sources: decision-record metadata
Merged
#591 feat(445,533): headless Playwright UI-E2E flows + fix e2e-local readiness probe
Merged
#601 fix(460): write null LastScan on disable-sync instead of the MinValue sentinel
Merged
#598 chore(586,594,485): PID-scoped E2E cleanup, ci-image-pin length guard, .gitignore core fix
Merged
#602 fix(500): dedup incoming metadata collections so a duplicate name inserts once
Merged
#588 chore(docs): trim derivable content from CLAUDE.md, lazy-load the task-completion protocol
Merged
#593 docs(592): record that a skipped CI context is not red
Merged
#589 feat(440): per-source weight steppers + exclude/add-untagged in the Auto-Tune DetailPanel
Merged
#585 chore(583): make per-agent model routing a hard constraint + PreToolUse gate
Merged
#584 feat(436): arbitrary-depth rule-builder group nesting
Merged
#579 feat(437): inline RuleBuilder smart-query authoring in Channel Builder
Merged
#581 feat(415): per-channel fault detection — server-derived health object + Problems filter
Merged
#577 feat(438,435,434): RuleBuilder validation, relative-date operators, DB-sourced facet typeahead
Merged
#575 feat(414): stamp immutable Channel.Origin (auto-tuned vs user-created) and surface it
Merged
#576 fix(458): reject duplicate names on playlist & playlist-group rename
Merged
#574 harden(421,559): percent-encode access_token in IPTV URLs, redact from logs, no-store on tokened manifests
Merged
#573 feat(392): per-schedule clock-boundary padding toggle + 60-min increment
Merged
#571 fix(570): On Now/Next overlay YAML renders (font_family + format_datetime)
Merged
#569 feat(74): per-channel On Now/Next transient overlay
Merged
#566 refactor(395): dedup Scripted≡YAML enumerator construction into ContentEnumeratorBuilder
Merged
#564 test(381): Sequential (YAML) playout golden; document Scripted deferral
Merged
#562 feat(297): add channelId to PlayoutListItemResponseModel; SPA reset keys directly
Merged
#561 fix(248): focus-trap the shared modal overlay so Tab can't escape a dialog
Merged
#560 fix(552): mint a short-lived JWT so the SPA reaches /iptv/* under JWT auth
Merged
#558 test(512): flush LibrariesScreen scan-poll chain deterministically instead of waitFor timeouts
Merged
#557 fix(553): exclude bot-authored issues from the queue selector
Merged
#551 feat(60): in-browser channel preview on the channels list
Merged
#556 docs(jellyfin-skill): correct stale "music videos are typed Movie" gotcha
Merged
#555 fix(177): map Album/Track in the Jellyfin music video projection
Merged
#550 fix(135): from-lineup advanced overrides can express "clear to none"
Merged
#546 fix(539): WorkAheadSlots.Release never publishes a negative count
Merged
#547 ci(545): require a **Signals:** line on decision records
Merged
#549 docs(skill): correct the ersatztv skill for the fork — it described upstream
Merged
#544 docs(542): record the workflow lore, then prune the kickoff doc to instructions
Merged
#543 chore(541): fast-forward the shared checkout at session end (H13)
Merged
#540 fix(68): rebuild on-demand channel guide (and mirrors) on thaw
Merged
#538 fix(536): enforce workAheadSegmenterLimit with an atomic slot claim
Merged
#537 ci(535): split PR-only git gates into pr-checks.yml so release tags don't red
Merged
#534 docs(524): triage #237's 111 comments — no decision retrofit is owed
Merged
#531 docs(release): v26.12.0 headline — ErsatzTV MCP server (#58) + external-logo download (#525)
Merged
#530 fix(529): floor QSV extra hardware frames so an unthrottled read can't exhaust the pool
Merged
#528 feat(525): external channel-logo URLs download + cache at save time (not fetched at render)
Merged
#527 feat(520,521): full decision-corpus migration + parallel-orientation startup rewrite (PR2 of 2)
Merged
#526 feat(521): decision-lifecycle machinery — keyed records, validator, generated catalog (PR1 of 2)
Merged
#518 fix(511): bound remote graphics-engine image fetches (timeout, size cap, decode cap, redirects, pooling)
Merged
#517 feat(#58): ErsatzTV.Mcp — read + cautious-write MCP server over /api/v1
Merged
#516 fix(350): burst-read the first HLS segments so cold start isn't readrate-bound
Merged
#513 fix(502): render the on-screen bug for external-URL channel logos
Merged
#514 docs(release): Komodo stack is jazz-media; no auto-update fallback
Merged
#509 ci: move both docker build jobs off the small lane
Merged
#507 docs(release): v26.11.0 headline is the QSV VA-API decode fix (#498) + unified logo bug (#67)
Merged
#506 feat(498): QSV profiles can decode via VA-API (Prefer native decoder)
Merged
#504 feat(67): one logo drives both the listing and the on-screen bug
Merged
#501 docs(release): prepare v26.11.0 promotion — correct the deploy host to jazz
Merged
#499 fix(497): reconcile music-video metadata collections on Jellyfin rescan
Merged
#490 docs(489): spec + implementation plan for Jellyfin mixed-content libraries
Merged
#493 feat(489): support Jellyfin mixed-content libraries
Merged
#495 fix(494): reconcile removed music videos in Jellyfin scanner
Merged
#492 fix(488): resolve LibraryFolder from DB so Jellyfin music-video scans stop crashing
Merged
#486 fix(480): probe external-JSON remote-stream URLs before ffmpeg
Merged
#482 feat(472): sub-split the HLS cold-start startup phase
Merged
#483 fix(477): guard media-server library sweeps against successful-but-empty fetches
Merged
#479 fix(473): probe media-server remote streams before handing the URL to ffmpeg
Merged
#481 fix(476): cascade FileNotFound from removed shows/seasons to descendants
Merged
#475 ci(412): sample true peak-anon in the test job, not cache-inflated memory.peak
Merged
#471 perf(469): format gate uses dotnet format whitespace --folder (~480s → ~0.5s)
Merged
#470 test(444): deterministic functional-E2E for the playout-build lock 409 + isLocked projection
Merged
#468 feat(431): TTL-cache health-check results; ?refresh=true forces a fresh run
Merged
#467 fix(464): render real channel logos in guide grid + channels list
Merged
#466 docs(404): mirror the weight UI into the MultiCollections design prototype
Merged
#465 fix(463): bound the schedules "Active schedule" selector so it stops overlapping the header
Merged
#462 feat(404): weighted-distribution SPA — per-source weight inputs + WeightedShuffle order
Merged
#461 feat(queue): deterministic select-queue.sh — stop re-deriving the selector by hand
Merged
#459 fix(409): report never-scanned LastScan as null for API/MCP parity (migration + read coercion)
Merged
#455 feat(420): skip re-validating an already-green identical merge tree
Merged
#457 feat(403): make unsupported PlaybackOrder loud at build time + tripwire
Merged
#456 fix(401): reject Mirror channel with playout (422) + repair dead else-branch
Merged
#454 fix(327): validate playlist name on rename (reject empty/whitespace/too-long)
Merged
#451 fix(409,447): LibrariesScreen 'Never scanned' label + stabilize flaky scan-poll test
Merged
#453 fix(410): log scan cancellation below ERROR (user-initiated, not a failure)
Merged
#452 ci(338): distinguish ZAP warning (exit 2) from failure (exit 1) in security-scan
Merged
#450 fix(367): correct Plex budget-exhausted guidance when no servers exist
Merged
#449 fix(310): strip UTF-8 BOM from the legacy .cs files #269 touched
Merged
#448 feat(396): collapsible sidebar + nav-group accordions
Merged
#446 feat(350): instrument HLS cold-start latency (phase split + feature flags)
Merged
#443 test(363): functional-E2E harness — deterministic scan-lock + collections-lock 409 flows
Merged
#442 feat(293): paginate GET /api/v1/search/all-items to cap DoS exposure
Merged
#441 fix(308): idempotent concurrent Add*ToCollection instead of a composite-PK 500
Merged
#439 feat(425): per-source rotation weights + query corrections for auto-tune channels
Merged
#433 feat(176): visual rule builder for the SmartCollection editor
Merged
#432 feat(386): Auto-Tune per-channel DetailPanel slide-over (SPA)
Merged
#430 feat(164): guided remediation for health checks
Merged
#428 feat(385): per-channel overrides in auto-tune bulk-create
Merged
#424 ci: pre-push guard against pushing an uncommitted working-tree change (H13)
Merged
#426 docs(lore): run local gate + cold review BEFORE pushing to Gitea CI
Merged
#429 fix(416): docs-only skip never fired — detect against FETCH_HEAD (shallow-checkout safe)
Merged
#423 fix(320): break troubleshoot segment-wait loop on ffmpeg failure
Merged
#422 ci(416): skip heavy jobs on docs-only changes without bricking the merge gate
Merged
#419 fix(376): XML-escape access_token value in XMLTV guide output
Merged
#402 feat(70): weighted / fair-share content distribution (WeightedShuffle playback order)
Merged
#417 docs(lore): batching, no "main checkout", trust the queue, diagnosing CI reds
Merged
#405 fix(72): report a real per-channel playout count and flag channels that will never play
Merged
#413 chore: PreToolUse guard that blocks a commit/push with a BOM'd touched .cs
Merged
#411 ci(406): disable persistent compiler servers, cap the services: mysql, report peak RSS
Merged
#407 ci: move api-docs and format back to ubuntu-latest (refs #406)
Merged
#408 fix(264): record library-level LastScan after a successful local scan
Merged
#397 feat(384): auto-tune DetailPanel content-source member read endpoint
Merged
#399 ci(390): shared CI toolchain image + drop 110s apt-ffmpeg + rebalance runner lanes
Merged
#391 feat(380): extract shuffle-source construction to ShuffleSourceBuilder (kill PlaylistEnumerator's cross-engine reach-in)
Merged
#394 design(388): mirror full ChicoryTV design system to prod + design-sync reminder hook
Merged
#393 test(77): characterize clock-boundary schedule padding + docs
Merged
#389 feat(69): Auto-Tune SPA wizard (Configure → Preview → Create) — PR2
Merged
#387 feat(71): per-playout reshuffle + shuffle-state surfacing
Merged
#382 test(163): golden characterization tests for playout building (Classic + Block)
Merged
#379 feat(69): auto-tuning backend — enumerate library metadata, preview + bulk-create channels (PR1)
Merged
#375 feat(analyzers): enable incremental latest-All enforcement
Merged
#378 fix(spa): body margin + nav box-sizing resets (#373, #377)
Merged
#374 feat(iptv): add configurable advertised base URL for M3U/XMLTV (#340)
Merged
#329 chore(deps): update dependency jetbrains.resharper.globaltools to 2025.3.4.1
Merged
#328 chore(deps): update dependency humanizer.core to 3.0.10
Merged
#370 ci(coverage): collect code coverage and publish a summary (refs #15)
Merged
#372 docs(queue): exclude parked selector candidates
Merged
#371 fix(api): protect local library path details
Merged
#369 docs(queue): cascade selector through priority tiers
Merged
#368 fix(api): report direct streams as on air
Merged
#366 fix(web): coherent, recoverable Plex authorized-but-no-servers state (#345)
Merged
#365 docs: make queue selection non-terminal
Merged
#362 ci: advisory functional-E2E curl harness (#299)
Merged
#361 refactor(web): extract ChicoryTV shell and routing
Merged
#359 refactor(web): extract Guide screen
Merged
#360 refactor(web): extract Dashboard screen
Merged
#356 docs(queue): record cheap-worker launch config
Merged
#352 docs(queue): start tool-bearing selectors at low effort
Merged
#351 refactor(spa): extract Playouts screen
Merged
#348 docs(queue): enforce milestone-aware picker ranking
Merged
#349 fix(spa): clear dirty guard before saved navigation
Merged
#346 docs(e2e): record real media-source validation results
Merged
#343 docs(workflow): enforce session-wide cost routing
Merged
#341 Add Cross-Origin-Resource-Policy baseline header
Merged
#337 docs(release): prepare v26.8.0 promotion
Merged
#331 feat(ci): #314 — authenticated black-box security scan + Microsoft.OpenApi HIGH-vuln pin
Merged
#325 fix(#172): API hardening — null-name 500s, duplicate template items, unreachable 404
Merged
#326 feat(api): #286 — mount the whole /api surface at /api/v1
Merged
#324 fix(#238): wire TopBar primary-action on create screens, drop dead buttons
Merged
#322 fix(api): #265 — If-Match evaluates per RFC 7232 (valid-but-non-matching -> 412)
Merged
#323 security(#319): enforcing CSP + Permissions-Policy on the host
Merged
#316 #295 PR2: SPA session cutover + #301 side-effecting-GET POST-ification
Merged
#321 feat(ci): #315 migration-on-prod-copy smoke for the release path
Merged
#318 fix(process): #317 merge-consent gate auto-grants on satisfied path (no double-prompt)
Merged
#313 process: #311 H11 rebase-hook + PR-scoped format CI + #312 H12 qualification audit
Merged
#309 docs(process): #303 follow-ups — Codex-skip rubric + write-path live-E2E requirement
Merged
#307 fix(api): #269 rotate aggregate ETag on Collection/Playout config siblings
Merged
#306 chore(process): #303 H10 — review-verdict merge-gate (latest commit must be reviewed)
Merged
#305 chore(process): #303 Wave 3 — H3 root-screenshot guard + H9 decisions.md append-only guard
Merged
#304 ci: #303 H4/H5 blocking api-docs gate — fail on stale OpenAPI artifacts
Merged
#302 fix(api): #269 force-write non-If-Match root writers past a concurrent Version bump
Merged
#300 feat(api): #295 PR1 — browser SPA session auth (session-OR-key gate, server-only)
Merged
#298 feat(api): #271 collections scan-status REST surface + authoritative SPA reconcile
Merged
#296 #197 Bundle C: OpenAPI contract honesty (#287) + wrap raw VMs / nullable DTOs (#288) + channel re-key
Merged
#291 security(#283): sniff artwork content type from bytes, remove serve-side ?contentType= reflection
Merged
#294 ci: make the MySql migration-apply resilient to concurrent-runner contention
Merged
#292 security(#197): fail-closed API auth posture (Bundle A: #280/#281/#282/#284/#285)
Merged
#290 docs(#197): record Phase-0 hardening decisions in decisions.md
Merged
#279 security(#197): safe hardening — constant-time key compare, clamp playout paging, security headers
Merged
#277 ci: prod follows :prod — remove version-pin bump job (#275 rework)
Merged
#276 #259: content-aware stable child identity for schedule-item replace
Merged
#275 ci: restore bump-prod-compose auto-deploy on v* release
Merged
#274 #91b — remove legacy Blazor Server UI
Merged
#273 chore(dev): husky pre-commit / pre-push / commit-msg guardrails
Merged
#270 feat(#253 PR3): optimistic-concurrency fan-out — Diff + Scalar aggregates
Merged
#268 #253 PR2 — optimistic-concurrency fan-out (Template, DecoTemplate, Playlist, schedule-items)
Merged
#272 #91b: wire deep-scan + external-collections buttons into LibrariesScreen
Merged
#267 feat(235): async-op API contract normalization + playout build observability + F9 scan endpoints
Merged
#266 fix(app): post-commit side effects on CancellationToken.None + guide-xml/empty-list hardening (#254)
Merged
#263 feat(api): optimistic-concurrency contract for replace-all PUTs — PR1 infra + Block reference (#253)
Merged
#262 feat(media-sources): SPA management screens + write REST API (#202)
Merged
#261 docs(91b): auth-posture sign-off + rollback-tag procedure for Blazor removal (#205, #206)
Merged
#260 fix(ui): pattern-based legacy→SPA redirect matcher for parameterized routes (#204)
Merged
#258 fix(scheduling): stop silently resetting fill-group state + invalidate deco edits (#251, #252)
Merged
#250 fix(locking): release troubleshooting + playout locks on all terminal paths (#233, #234)
Merged
#249 refactor(spa): extract ChannelsScreen from App.tsx (#244, epic #243 phase 1)
Merged
#242 fix: reviewer post-merge blockers — empty-lineup bare create (#212) + dirty-guard popstate/shuffle-toggle (#230)
Merged
#241 fix(locking): EntityLocker atomicity + scan-lifecycle honesty (#231, #232)
Merged
#229 feat: schedules editor full mutation depth + channel-editor gaps (#207, #212, #126)
Merged
#240 test(api): locked-path 409 guard tests for ReplaceAlternateSchedules + ReplaceTemplates (#215)
Merged
#239 Integration: review-gates batch — #220/#215/#217/#219/#218 + #213 remainder (PRs #223–#228)
Merged
#222 fix(spa): gate mutation controls on stale result sets during refetch (#221)
Merged
#216 feat: shared Add-to layer — search + media mutation surface (#208, #209)
Merged
#214 feat: playouts delete/reset/erase + collections custom-order/all-kind adds + parity nits (#210, #211, #213)
Merged
#201 fix(openapi): spec property naming now mirrors the runtime Newtonsoft serializer (#198)
Merged
#200 fix(api): existence-check rerun-collection selectedId per selection type (#193)
Merged
#199 feat: SPA playback troubleshooting screen + status/subtitles/stream-selectors endpoints (#145)
Merged
#196 docs+ci: harden docs-first rule + non-blocking parity-doc reminder
Merged
#195 feat: playlist CRUD API + SPA editor (#153)
Merged
#194 feat(spa): multi-collection & rerun-collection editor screens (#151, #152)
Merged
#192 ci: speed up build pipeline (NuGet cache, shallow checkout, jar layer reorder) (#190)
Merged
#188 feat(api): REST CRUD for multi-collections and rerun-collections (#151, #152)
Merged
#189 feat(api): GET /api/collections/{id}/items (paged) — full collection contents (#155)
Merged
#187 feat: quick wins — security-registry scan, Trakt SPA link, parallel search, dead "New Group" sweep
Merged
#186 docs: testing map + generated endpoint index (#185)
Merged
#183 feat(web+api): media detail endpoints+pages, image folder browser (#141, #161 items 3+5)
Merged
#182 feat(web+api): block-playout history + sequential-YAML validator (#145, #158 items 4–5)
Merged
#181 fix(web+api): library picker artwork URLs + season drill-in instead of tile flooding (#180)
Merged
#179 feat(web+api): playout alternate schedules + templates editors, default-deco read-side (#144 S6, #162)
Merged
#175 feat(web+api): deco templates (#144 S4, #162)
Merged
#174 feat(web+api): decos + deco groups, playout default deco, playlist/search pickers (#144 S3, #162)
Merged
#173 feat(web+api): scheduling templates + block/template copy (#144 S2, #162)
Merged
#171 feat(web+api): blocks CRUD, items editor & preview (#144 S1, #162)
Merged
#170 feat(web+api): playout create for all kinds + detail updates (#144 S5, #162)
Merged
#168 feat(web+api): media browse, search & trash for SPA parity (#141)
Merged
#169 test(web): make Libraries scan-polling tests deterministic (fixes #157)
Merged
#167 feat(web+api): Trakt lists screen + REST API for SPA parity (#142)
Merged
#166 feat(web+api): FFmpeg profile, filler preset & watermark editors for SPA parity (#143)
Merged
#165 feat(web+api): logs & troubleshooting screens for SPA parity (#145)
Merged
#156 feat(web): collections management screen — manual + smart collections (#140)
Merged
#154 feat(web): dedicated channel edit screen (#146)
Merged
#150 feat(web): Classic UI link in Settings + ChicoryTV cue on redirecting Blazor nav links (#147)
Merged
#132 chore(deps): update dependency entityframeworkprofiler.appender to 6.0.6053
Merged
#61 chore(deps): apply open Renovate patch updates
Merged
#148 feat(web): SPA cutover — root route (#91)
Merged
#139 feat(web): ChicoryTV rebrand (#90)
Merged
#138 feat(web): Settings screen (#93)
Merged
#137 fix(deps): bump Scriban.Signed 6.5.2 → 7.2.5 (GHSA-5wr9-m6jw-xx44)
Merged
#136 feat(web): Channel Builder (#89)
Merged
#134 feat(api): composite create-channel endpoint (#63)
Merged
#133 feat(api): channel templates entity + CRUD (#64)
Merged
#130 feat(api): library browse + search endpoints (#65)
Merged
#129 feat(web): Guide / EPG screen (#85)
Merged
#128 feat(web): Libraries screen (#88)
Merged
#127 feat(web): Playouts screen (#87)
Merged
#125 feat(web): Schedule editor screen (#86)
Merged
#124 feat(web): Channels screen (#84)
Merged
#123 feat(web): Dashboard real data sources (#109)
Merged
#121 feat(core): track active sessions for direct streaming modes (#99)
Merged
#122 fix(docker): use valid node:22-bookworm-slim base for web-build stage
Merged
#120 feat(web): ChicoryTV SPA foundation (#59 stack)
Merged
#112 feat(api): channel on-air / now-playing state endpoint (#97)
Merged
#119 feat(api): JSON channel guide endpoint (#102)
Merged
#118 feat(api): schedule item duration estimates (#111)
Merged
#117 feat(api): artwork upload endpoint (#104)
Merged
#115 feat(api): media sources + scan status endpoints (#103 #106)
Merged
#116 feat(api): playout read endpoints (#100 #101 #107 #110)
Merged
#114 feat(api): health endpoints (#108)
Merged
#113 feat(api): filler/watermark/graphics list endpoints (#105)
Merged
#56 fix(ffmpeg): align transcode pipelines with ffmpeg 8
Merged
#55 feat(jellyfin): sync MusicVideo libraries
Merged
#54 feat(api): default-deny mutating API writes
Merged
#53 test: make channel logo generator testable
Merged
#52 feat(api): standardize FFmpeg profile endpoints
Merged
#51 feat(api): add playout REST endpoints
Merged
#50 feat(api): add schedule REST endpoints
Merged
#47 fix(api): standardize error response contract
Merged
#45 feat(api): add collections REST endpoints
Merged
#44 feat(api): REST API foundation + Channels CRUD (#2a)
Merged
#41 fix: make filler scheduling tests timezone-independent (fixes #24)
Merged
#40 test: golden tests for XMLTV guide output (#28)
Merged
#33 ci: gate image build on migrations + #1 handoff
Merged
#32 docs: retroactive contributors/style guide (#10)
Merged
#31 ci: assert key IPTV endpoints in the container smoke test (#16)
Merged
#30 ci: EF migration integrity checks for SQLite + MySql (#13)
Merged
#29 test: golden-file tests for M3U output (#11)
Merged
#27 test: enforce layer dependency direction with NetArchTest (#12)
Merged
#26 build: static-analysis pack foundation at suggestion (#15, increment 1)
Merged
#23 ci(renovate): enable Dockerfile manager for the HTTP Gitea registry
Merged
#20 fix(deps): clear NCalcSync + SQLitePCLRaw vulnerability advisories (#8)
Merged
#19 ci(renovate): fix GitHub PAT secret name + bump image pin
Merged
#18 ci: self-hosted Renovate (NuGet CPM + Gitea Actions)
Merged
#17 build: Central Package Management + scheduled vulnerability scan (#14)
6 Pull requests proposed by 2 users
Proposed
#761 chore(deps): update dependency meziantou.analyzer to 3.0.195
Proposed
#804 chore(deps): update dependency sqlitepclraw.bundle_e_sqlite3 to 3.0.5
Proposed
#805 chore(deps): update dependency system.commandline to 2.0.11
Proposed
#828 chore(deps): update dependency cliwrap to 3.10.5
Proposed
#829 chore(deps): update lucene.net to 4.8.0-beta00018
Proposed
#878 fix(830): a write failure reports to a surface that outlives the dialog that started it
416 Issues closed from 1 user
Closed
#876 docs.no-session-narrative reaches hooks and code comments, but nothing has ever swept them — 4 known sites
Closed
#893 page_statuses still terminates on its first empty page — is /statuses/{sha} subject to #870's post-pagination filtering?
Closed
#869 Finish the 1.25.4-dated CI claim sweep #747 deliberately did not complete
Closed
#891 ETV_HOOK_FIRE_LIB is SOURCED from an env-var path in 12 hooks — a decoy tree's code runs inside the gate
Closed
#855 Nothing couples ci-image.yml's push.paths to ci-image-pin's expected pathspec
Closed
#887 Every image build fails: completeAnnotations.guard.test.ts needs the git index, and the Dockerfile's exclude list is hand-maintained
Closed
#900 chore(release): cut and promote v26.15.0 on 736649b3b (main head could not build an image)
Closed
#858 pretooluse-merge-consent.sh resolves its verdict classifier from $CLAUDE_PROJECT_DIR — an env var as a security input
Closed
#859 Merge-gate branch-protection read: a malformed rule states a cause that did not happen, and the endpoint is now fetched twice
Closed
#870 The timeline walk's null terminator is defeatable: Gitea pages BEFORE it filters, so a page of inline-code comments reads as exhaustion
Closed
#880 Schedule-item recurrence fields: an omitted array means "never applies" on write but "unrestricted" on read
Closed
#849 review-verdict.yml post-write verification: three routes that leave an exemption success over a human failure
Closed
#845 post-review-verdict.sh does not check that its own account is on the gate's H10_REVIEWERS allow-list
Closed
#886 release.verdict-vocabulary-shared explains the sentinel with a set -u mechanism that measurement refutes
Closed
#853 workflow_dispatch still loads attacker YAML from an arbitrary ref — four workflows, no ref restriction
Closed
#836 :latest images ship InformationalVersion 0.0.0 — a --depth=2 fetch grafts the build job's full clone shallow
Closed
#820 Complete<T> proves its semantics but not its APPLICATION — nothing derives the set of SPA full-replace construction sites
Closed
#812 Remediate the 21 session-narrative sites #784's sweep found — 21 judgements, not a regex
Closed
#823 Scheduling collection-valued columns: is a runtime null reachable on DaysOfMonth / MonthsOfYear / DaysOfWeek?
Closed
#824 ElasticSearchIndex.UpdateSong has no regression test — an Elastic-only reintroduction of the #701 mutation stays CI-green
Closed
#819 The SPA page-size guard enumerates web/src with a Vite glob while claiming completeness
Closed
#809 The production-hook-fire-log isolation guard is per-test, but its claim is per-suite
Closed
#822 test_the_suite_does_not_write_to_the_PRODUCTION_log uses global mutable state as its oracle — any concurrent session reddens it
Closed
#664 pr-changed-files.sh head binding cannot see an A→B→A force-push across its paging round-trips
Closed
#803 Head-ABA: a force-push H1->H2->H1 during paging defeats pr-changed-files.sh, and three contracts still deny it
Closed
#789 Derive the CI toolchain population from workflow-owned metadata, not TOOLCHAIN_JOBS
Closed
#786 Extend the machine-checked guard inventory to inline workflow-job guards
Closed
#796 A verification harness is itself unproven code — five false greens, each created by the fix for the last
Closed
#763 Page both /statuses/{sha} reads in review-verdict.yml — limit clamps to 50, so the post-write race check can miss a raced verdict
Closed
#747 Re-verify the Gitea 1.25.4-pinned CI claims after the 1.27.1 upgrade
Closed
#781 Plugin/MCP config hygiene: retire what is enabled and never invoked, de-duplicate the gitea server
Closed
#799 serena is enabled and starts fine, but its tools never reach a session — establish why, then use or disable it
Closed
#787 The dropped-step guard's SCOPE is a dated comment, not a check, against branch protection
Closed
#748 Declare permissions: on the status-writing workflows so the Gitea Restricted token default can be enabled
Closed
#744 ci-image.yml's push trigger has no branches: filter — any branch push runs attacker YAML on a docker-capable runner
Closed
#835 Guard the persist-credentials convention — after #744, with no exemption list
Closed
#742 Tighten review-verdict.yml provenance from "non-null creator" to an allow-list of approved reviewers
Closed
#735 Validate FFmpeg profile numeric fields to sane ranges instead of silently transforming them, and expose readrate pacing as a bounded field
Closed
#788 One shared verdict vocabulary instead of two shell copies plus a parity test
Closed
#732 On Now / Next overlay: give it a boxed background for legibility, and enable it on all channels by default
Closed
#746 docker-build.yml checkouts should set persist-credentials: false — after the || true fetch masking is removed
Closed
#734 SPA: field-level progressive disclosure — short summary → hover popup → (future) deep-dive docs link
Closed
#755 Project boundary: ersatztv owns the fork code, media-management owns channel operations
Closed
#708 Reproduce #698 route 2 live: push code onto a renovate-authored PR branch and confirm the manifest allow-list refuses the exemption
Closed
#690 Rerun collections: paged list TotalCount ignores the search query, so the SPA renders empty pages
Closed
#758 GetPagedPlayouts: TotalCount ignores the query filter, so a filtered page reports the unfiltered total
Closed
#721 Auto-Tune proposal rows should be a grid — channel numbers do not line up, and the name renders twice
Closed
#740 AddItemsDialog.runSearch has no stale-response or is-mounted guard (pre-existing, surfaced during #685)
Closed
#807 The SPA's hand-built request objects can silently drop an OPTIONAL DTO field
Closed
#701 Search indexers mutate SongMetadata.Artists on a possibly-tracked entity (??= []) — same shape rejected in #691
Closed
#792 post-review-verdict.sh exits 0 when it deliberately writes NO status
Closed
#772 The pinned CI toolchain image can vanish from the registry and take ALL container CI down, with no signal but a pull error
Closed
#806 Guard populations over FILES should derive from the git index, not a filesystem walk
Closed
#790 An executable clause-level mutation harness for the shell and python guards
Closed
#780 Reconcile Python tooling: commit a ruff config and enforce it, or stop claiming we enforce it
Closed
#784 Generalize the no-session-narrative rule from the kickoff file to all docs — the reader never saw the earlier draft
Closed
#785 Mutation proofs for the 19 unproven guards, worst-consequence first
Closed
#779 Test the deny path with the production config value, and assert full-replace field lists
Closed
#778 Audit read-then-write against live remote state: pin a version or use compare-and-set
Closed
#794 A fix ships a test witnessed failing BEFORE the fix — mechanise it by reverting the code side and asserting red
Closed
#776 Make hooks report that they fired — PreToolUse/PostToolUse execution is currently unobservable
Closed
#797 pretooluse-bom-guard.sh is fail-open wherever xxd is not installed — including the CI runner
Closed
#777 csharp-lsp and typescript-lsp are broken; the "workflow agents must use csharp-lsp" guidance is stale
Closed
#774 Guard convention: derive the expected set from the authoritative source and assert equality — never filter, never sample
Closed
#775 Every guard ships with a proof it can go red: delete that guard alone, the suite must fail
Closed
#773 Root-cause the recurring defect shapes across closed issues, then build hooks/tooling that make them hard to repeat — plus an audit of the tooling we already have and don't use
Closed
#767 Make the delimiter ban fail-CLOSED on the release path — build's Smoke step is still droppable on a v* tag push
Closed
#720 docs(ci-cd): a Komodo stack named ersatztv now exists on jazz — and it is NOT prod
Closed
#756 Extend the dropped-step guard to docker-build.yml's required jobs, where a dropped step is fail-OPEN
Closed
#751 review-verdict.yml's classify/post step never executes — job goes green, review-verdict/h10 is never posted automatically
Closed
#754 MCP ersatztv_update_channel omits graphicsElementIds — cannot set the On Now/Next overlay, and silently strips it
Closed
#757 MCP tool catalog: query parameters are unguarded — list_playouts omits query, get_playout_items omits showFiller
Closed
#719 H11 pre-push guard blocks a tag-only push, on every release cut
Closed
#743 review-verdict/h10 is bypassable without forging it: direct pushes to main are server-side permitted
Closed
#697 ETV_STATUS_AUTH can write commit statuses, so any head-resolved workflow can still forge review-verdict/h10
Closed
#685 CollectionsScreen AddItemsDialog windows the whole media-library type on an empty query, with no truncation surfaced (§3b deviation)
Closed
#674 decisions_validate.py stays green on frontmatter PyYAML rejects — an apostrophe in a single-quoted scalar (hit twice in one session)
Closed
#688 decisions_validate ceiling calibration test is one line from red — any record ≥61 prose lines fails script-tests
Closed
#726 Embedded BITMAP subtitle (PGS/DVD) burn-in + -readrate halves transcode to 0.53x realtime — Live TV buffering
Closed
#707 pr-changed-files.sh paging can drop a path when the base branch advances mid-enumeration
Closed
#711 .codex/ mirrors the gate-enforcing hooks but is absent from the merge gate's PROTECTED list
Closed
#706 review-verdict/h10 writes are not serialized — a stale run can overwrite a fresher verdict (ABA retarget + human-rejection race)
Closed
#715 chore(deps): land the three stalled Renovate patch bumps as one batch (#679, #680, #681)
Closed
#713 chore: ignore .codex/ and stop shipping a plaintext Gitea credential in tracked docs
Closed
#698 The review-verdict/h10 exemption path decides from mutable PR state — three routes to a forged exemption
Closed
#672 review-verdict.yml is head-resolved, so a PR editing it can self-approve the required check
Closed
#691 SongVideoGenerator dereferences the nullable SongMetadata.Artists unguarded — NRE on the playback path
Closed
#671 Rerun collections: the list endpoint returns a null selection for every row, and the detail GET 500s or nulls for five media types
Closed
#668 Facet-value typeahead misses accented values on the EF-sourced fields (LOWER() is ASCII-only on SQLite)
Closed
#684 main is red: the #650 pageSize call-site guard keys its registry on line:column, so any merge that shifts a line breaks it
Closed
#578 #434 follow-ups: typeahead combobox polish + source limitations
Closed
#650 Two more list loads truncate at the cap — but at-cap, so #644's over-cap grep could not see them
Closed
#651 Library-browse pickers need a searchable source, not a 100-row window or a full-library crawl
Closed
#649 The ENFORCED review-verdict.yml guard is weaker than the advisory local hook — duplicated security logic has drifted
Closed
#632 A PR base change leaves the head sha — and so the review-verdict/h10 status — unchanged
Closed
#662 Typeahead artist suggestions miss free-text credits; album_artist 404s — value-converted list columns have no suggestion source
Closed
#648 Pin or preflight jq in CI: the runner ships 1.6, dev machines ship 1.8.x, and that gap silently broke three shell gates
Closed
#510 WatermarkSelector: the deco path has a different missing-logo policy than the three precedence levels
Closed
#644 Seven more SPA list loads silently truncate at the server cap (same class as #634, one screen over)
Closed
#505 QSV native-decode path tonemaps HDR in software (route through tonemap_qsv)
Closed
#620 decisions corpus consolidation has no owner — and after #610 the budget number stops reporting it
Closed
#647 H10 verdict classifier is inert on jq 1.6: contains("�") matches every string, and a parse error is indistinguishable from an empty list
Closed
#643 Merge-consent gate fails OPEN on jq 1.6: a transport failure mid-pagination lets the docs-only exemption fire over a PARTIAL file list
Closed
#631 scripts/tests/ is never executed by CI — the Python test suite is local-only
Closed
#621 decisions: a record file that fails to parse is silently invisible — no structural "one keyed record per file" check
Closed
#633 OpenAPI pageNum parameters carry no description, so the 0-based contract is invisible to REST consumers
Closed
#634 Rerun-collection picker in SchedulesScreen silently truncates at 100 (asks for pageSize 1000, server clamps to 100)
Closed
#629 merge gate: false-opens in the H10 verdict classifier — an undefined token, code blocks (fenced/indented/HTML), a URL-borne sha, and a read path that failed open
Closed
#617 .claude/skills/jellyfin/ is a stale divergent copy, not the symlink CLAUDE.md describes — it documents auth that v12 only accepts by legacy opt-in
Closed
#615 Jellyfin merges <Base> - <variant>.mp4 music videos into one multi-version item — Behind the Music (61 files) and Top of the Pops (24 files) each land as a single ErsatzTV item
Closed
#616 MCP/API paging traps: pageNum documented 1-based but is 0-based, pageSize cap doesn't clamp the offset, and playout rows carry no channelId
Closed
#622 merge gate: docs-only exemption is computed from a TRUNCATED file list (confirmed); auto-merge scheduling also freezes H10 consent (structural)
Closed
#491 LibraryFolder has no unique index on (LibraryPathId, Path) — concurrent GetOrAddFolder can insert duplicates
Closed
#610 decisions: split the monolithic corpus into one YAML-frontmatter file per record
Closed
#609 decisions-validate: [decisions-edit] is a bare substring match — a commit that merely *describes* the token disarms the guard
Closed
#496 Music videos have no per-library identity — global GetOrAdd path dedup can cross-library false-trash
Closed
#487 MCP acceptance case: populate the empty music collections via the MCP write path (not by hand)
Closed
#484 Media-server scanner: ratio-threshold + projection-failure detection for the empty-fetch guard
Closed
#503 Watermark MiddleCenter renders bottom-right — missing switch arm in OverlayWatermarkFilter
Closed
#603 decisions: adopt OKF's stale-after and Sources: as optional record metadata
Closed
#445 functional-E2E: add the UI-interactive Playwright (headless) flows (deferred from #363)
Closed
#533 scripts/e2e-local.sh readiness probe hangs on a reused config dir
Closed
#460 MediaSourceRepository writes MinValue LastScan on disable-sync — normalize to null (#409 follow-up)
Closed
#485 Build hygiene: .gitignore core entry silently ignores new files under any Core/ directory (case-insensitive on macOS)
Closed
#586 E2E briefs: scope process cleanup by PID, never a pattern-wide pkill
Closed
#594 ci-image-pin accepts any hex length, not the exact 7-char tag ci-image.yml publishes
Closed
#500 MediaServer metadata reconcile double-inserts on duplicate collection names (Plex movie + Jellyfin music-video update paths)
Closed
#587 chore(docs): trim derivable content from CLAUDE.md and lazy-load the task-completion protocol
Closed
#592 CI monitors: record that skipped is not red (build skips on every PR)
Closed
#440 Auto-Tune DetailPanel SPA: wire per-source weight steppers + exclude/add-untagged to the #425 backend
Closed
#583 Kickoff: make per-agent model routing a hard constraint + a PreToolUse gate
Closed
#436 Rule builder: support nesting deeper than one level (#176 follow-up)
Closed
#437 Adopt RuleBuilder inline in ChannelBuilder & Auto-Tune (#176 follow-up)
Closed
#415 Per-channel fault detection beyond "no playout" (empty schedule, broken source)
Closed
#434 Rule builder: facet-value typeahead for text fields (#176 follow-up)
Closed
#435 Rule builder: relative-date operators ("in the last N days") (#176 follow-up)
Closed
#438 Rule builder: input validation & polish (bundles #176 review minors)
Closed
#414 Channels list: distinguish auto-tuned from user-created channels (origin marker)
Closed
#458 Playlist/group rename should reject duplicate names (like create does) — #327 follow-up
Closed
#178 Idea (far future): Jellyfin plugin to control ErsatzTV from within Jellyfin
Closed
#75 [Blue sky] Themed "Resource Packs" for bumpers / branding / interstitials
Closed
#559 Harden the /iptv ?access_token= transport: redact from request logs + no-store on tokened manifests
Closed
#421 M3U: access_token value not quote-safe in url-tvg="..." attribute
Closed
#392 Clock-align convenience: one-click per-channel/schedule pad-to-boundary toggle + 60-min increment (SPA)
Closed
#570 On Now/Next overlay YAML fails to render (format_datetime arity + null font_family) — #74 hotfix
Closed
#567 Harden channel graphicsElementIds: validate unknown ids (422 not 500) + builtIn discriminator (#74 follow-up)
Closed
#74 [Blue sky] On-screen "On Now / On Next" overlay (channel-surf bug)
Closed
#395 Refactor: dedup Scripted≡YAML enumerator construction (deferred from #380, gated on #381 goldens)
Closed
#523 QSV native-decode (#498) hwupload fails to allocate a QSV surface for certain content — "Cannot allocate memory" kills the stream
Closed
#381 Golden characterization tests for remaining scheduler kinds (Sequential YAML + Scripted)
Closed
#297 Add channelId to PlayoutListItemResponseModel so the SPA reset button keys directly
Closed
#248 SPA dialogs (overlay.tsx) are not focus-trapped / background-inerted
Closed
#552 Mint a short-lived JWT for the SPA so /iptv/* works under JWT-enabled deployments
Closed
#512 Make LibrariesScreen scan-complete test deterministic (stop racing real microtasks under waitFor)
Closed
#553 select-queue.sh ranks Renovate's bot-authored Dependency Dashboard (#22) as a workable pickup
Closed
#60 Backlog: browser channel playback after UI redesign
Closed
#177 Jellyfin music video sync: map Album/Track metadata (credits-overlay completeness)
Closed
#62 Epic: Create Channel — backend prerequisites for the redesigned creation flow
Closed
#135 from-lineup advanced overrides cannot express "clear to none" (null = inherit template)
Closed
#539 WorkAheadSlots.Release hardening: never go negative, and surface UnbalancedReleases somewhere a human will see it
Closed
#545 decisions-guard: require a **Signals:** line (MemPalace recall metadata contract)
Closed
#548 docs: the ersatztv skill described archived upstream, not this fork
Closed
#542 The kickoff handoff doc should be instructions, not incident history — prune the narrative into decisions.md
Closed
#541 H13: session-end must leave the shared checkout fresh — a stale tree serves stale FILES, which no HEAD-reading rule catches
Closed
#68 Resume/bookmark playback position for sequential channels (personal continue-watching)
Closed
#536 workAheadSegmenterLimit is not enforced: the slot check and its increment straddle an await (N concurrent tune-ins all run unthrottled)
Closed
#535 Release-tag builds: small-lane PR-only gate jobs run + fail on v* tag pushes
Closed
#532 Re-measure HLS cold start on prod after v26.12.0+ ships the #529 floor, against #350's 13-sample baseline
Closed
#524 Retrofit #237's durable-only facts into #521 decision records (post-arc follow-up)
Closed
#519 Verify the #350 cold-start burst end-to-end on test, then re-measure on prod
Closed
#529 QSV extra_hw_frames=0 kills transcodes on any unthrottled read — live in prod, and made near-deterministic by #516's burst
Closed
#525 External channel-logo URLs: download + cache at save time instead of fetching at render time
Closed
#521 Make decision knowledge lifecycle-addressable and retrieval-efficient
Closed
#520 Retire #237 from startup; run orientation and mechanical top-five selection in parallel
Closed
#511 Harden remote-image fetching in the graphics engine (timeout, size cap, redirects, pooling, caching, SSRF)
Closed
#58 Backlog: MCP server for ErsatzTV/ChicoryTV API
Closed
#350 Channel cold-start ~7s to first segment — slow tune-in via Dispatcharr/Kodi (heavy transcode profile)
Closed
#502 External-URL channel logos never render an on-screen bug (File.Exists against a URL in WatermarkSelector)
Closed
#515 release: cut and promote v26.11.0 to prod (first release on jazz)
Closed
#474 Music channels dead: Music Videos library has no LibraryPath, so /data/music (30 folders) is never scanned — 8+ collections empty
Closed
#508 Move the two docker build jobs off the small runner lane
Closed
#498 FFmpeg profile should allow separate decode and encode hardware acceleration (QSV encode + VAAPI decode)
Closed
#67 Unified logo/bug image handling (one image drives both, separable)
Closed
#25 Burn down SonarAnalyzer findings in Blazor .razor (analyzer adoption #15)
Closed
#497 JellyfinMusicVideoLibraryScanner.UpdateMetadata drops Tags/Genres/Studios on existing items — Jellyfin metadata edits never sync
Closed
#489 Support Jellyfin mixed-content libraries (currently dropped silently) — keep music/standup segregated from Movies & TV Shows
Closed
#494 JellyfinMusicVideoLibraryScanner does no reconciliation — music videos removed from Jellyfin are never removed from ErsatzTV
Closed
#488 JellyfinMusicVideoLibraryScanner crashes immediately: ArgumentNullException from null LibraryPath.LibraryFolders (feature has never worked)
Closed
#480 External-JSON playout channels still hand ffmpeg an unprobed remote-stream URL (#473 class survives there)
Closed
#472 Split HLS cold-start startup phase into spawn / input-open+probe / first-GOP
Closed
#477 Scanner has no anti-nuke guard: a successful-but-empty media-server fetch flags an entire library FileNotFound
Closed
#478 Channels 102/107 repeatedly fail to tune: h264_vaapi hwupload -22 / exit 234 on prod
Closed
#473 Tune-in hard-fails (ffmpeg exit 8) when a playout item's media file no longer exists — 717 stale episodes across 10 removed shows on prod
Closed
#476 Scanner: FileNotFound does not cascade show → seasons → episodes, so playouts keep scheduling episodes of shows deleted upstream
Closed
#412 CI: peak-memory instrument reports cache-inflated memory.peak; sample true peak anon instead
Closed
#469 CI: speed up the Formatting job (dotnet format --include still loads the whole solution)
Closed
#444 functional-E2E: add the playout-build lock 409 + isLocked projection flow (deferred from #363)
Closed
#431 Backend: TTL-cache PerformHealthChecks (GET /api/v1/health re-runs 14 checks, 4 shell out to ffmpeg, per request)
Closed
#464 Guide + channels list show generated fallback icons instead of the actual channel logo
Closed
#463 Schedules screen: "Active schedule" selector stretches full-width and overlaps the header
Closed
#404 SPA: per-source weight inputs + fair-share toggle in the schedule editor (#70 UI)
Closed
#409 Never-scanned local libraries render "Last scan 12:00 AM" instead of "Never scanned" (LastScan seeded as DateTime.MinValue, not NULL)
Closed
#420 CI: PR run and merge-to-main run re-execute the full matrix over identical code
Closed
#403 Scheduling: an unhandled PlaybackOrder fails silently at five of six dispatch sites
Closed
#398 CI: build once, reuse artifacts across test / migrations / functional-e2e (742s of redundant compilation per run)
Closed
#401 UpdateChannel silently coerces Mirror→Generated when the channel has a playout (should be 422)
Closed
#327 Playlist rename (ReplacePlaylistItems) does no name validation — empty / >50-char names accepted
Closed
#447 Flaky SPA test: LibrariesScreen "stops scan polling and refreshes sources once when scans complete"
Closed
#410 Scan cancellation is logged at ERROR ("Scan was canceled") across all four scan handlers
Closed
#338 ci: distinguish ZAP warning exit 2 from FAIL in security-scan
Closed
#367 Plex: budget-exhausted message says "Use Refresh" but there is no global Refresh when zero servers exist
Closed
#310 De-BOM the 17 legacy .cs files #269 touched (charset=utf-8 violation)
Closed
#383 Auto-Tune: per-channel configuration (DetailPanel) — editable per-channel step
Closed
#396 Collapsible left sidebar + collapsible nav groups
Closed
#363 functional-E2E harness: add the deferred media/lock/Playwright flows (follow-up to #299)
Closed
#293 Page/cap GET /api/search/all-items (DoS hardening — deferred from #285)
Closed
#308 Concurrent same-item Add*ToCollection can 500 on composite-PK violation (pre-existing idempotency-under-concurrency gap)
Closed
#425 Auto-Tune DetailPanel: per-source rotation weights + query corrections (weighted-distribution redesign)
Closed
#176 Rethink channel/playout/schedule creation: PseudoTV-style channel-first flow with a Kodi-smart-playlist-like query builder
Closed
#386 Auto-Tune DetailPanel: per-channel editor slide-over (SPA)
Closed
#164 Health checks UX: audit usefulness + guided/automated remediation
Closed
#385 Auto-Tune DetailPanel: per-channel overrides + rotation weights in bulk-create
Closed
#320 TroubleshootController playback segment-wait loop doesn't check notifier.IsFailed (spins until client cancel if ffmpeg dies)
Closed
#416 CI: docs-only changes run the full build/test matrix (~9 min) for nothing
Closed
#376 XMLTV: access_token query value interpolated raw into guide (pre-existing XML-injection)
Closed
#70 Weighted / fair-share content distribution (playback order)
Closed
#72 Channel lineup health at-a-glance (status states in the channels list)
Closed
#406 CI: cut peak build RSS (Roslyn), cap the services: mysql, and move api-docs/format back to ubuntu-latest
Closed
#264 Local libraries always show "Never scanned" — local scanner sets path-level LastScan but not library.LastScan
Closed
#59 Backlog: full UI redesign and ChicoryTV rebrand
Closed
#384 Auto-Tune DetailPanel: enumerate a SmartCollection's distinct members (read endpoint)
Closed
#390 CI: shared toolchain base image (.NET 10 SDK + Node 22 + ffmpeg) for CI jobs
Closed
#73 Seasonal / date-conditional channels & schedule rules
Closed
#380 Refactor: shared enumerator-construction/state seam for PlaybackOrder across scheduling engines
Closed
#388 Mirror the ChicoryTV design system to prod (Claude Design ↔ shipped SPA)
Closed
#77 Pad/snap channel schedules to clock boundaries (:00/:15/:30) using filler
Closed
#69 Auto-tuning: generate channels automatically from library metadata
Closed
#357 Jellyfin/Kodi PoC: player-owned channel playback with ErsatzTV as channel engine
Closed
#71 Persistent shuffle state + explicit "Reroll" control
Closed
#163 Golden-style characterization tests for playout building
Closed
#15 Adopt a C# lint/format/static-analysis stack (the ruff equivalent) and enforce in CI
Closed
#373 bug(spa): white border around the edges of the login / boot pages (missing body margin reset)
Closed
#377 SPA: left sidebar scrolls horizontally (unwanted overflow-x)
Closed
#340 Add configurable advertised IPTV base URL for M3U/XMLTV output
Closed
#333 test: run #202 real-server media-source integration validation
Closed
#334 security: keep local-library filesystem paths authenticated when reads are open
Closed
#354 ChicoryTV: subtitles progressively run ahead of dialogue during playback
Closed
#99 Backend: track active sessions for MPEG-TS and HLS-Direct streams
Closed
#345 Plex pin flow reports connected but strands authorized accounts with no servers
Closed
#364 docs: make queue selection non-terminal
Closed
#299 CI: codify the manual live-E2E flows into an automated functional-E2E harness
Closed
#243 Refactor ChicoryTV App.tsx into screen-owned modules and a small app shell
Closed
#247 Extract ChicoryTV shell/routing and replace implicit TopBar action coupling
Closed
#246 Extract Dashboard and Guide screens from App.tsx
Closed
#355 docs: record tested Codex cheap-worker launch configuration
Closed
#353 docs: start tool-bearing selectors at low effort
Closed
#245 Extract PlayoutsScreen and playout UI helpers from App.tsx
Closed
#347 Queue selector skips milestone work and repicks completed reviewer audits
Closed
#344 Saving a remote connection falsely triggers the dirty guard
Closed
#342 Enforce session-wide low-cost routing for bounded reconnaissance
Closed
#330 Add Cross-Origin-Resource-Policy header (ZAP #314 authenticated-scan Low)
Closed
#339 docs: require low-cost queue selection preflight
Closed
#237 ChicoryTV rewrite — queue tracker (goal, arc, session protocol)
Closed
#335 release: cut v26.8.0 and complete ChicoryTV go-live
Closed
#336 docs: prepare the v26.8.0 release boundary
Closed
#197 Cold adversarial review: REST API contract + security posture (pre-ossification)
Closed
#332 docs: make ChicoryTV queue handoff client-neutral
Closed
#314 Out-of-ecosystem black-box security scan against the running container (#197 exit criterion)
Closed
#172 Scheduling API hardening follow-ups from #144 S1/S2 reviews
Closed
#286 #197 C1 [BLOCKER]: no API versioning — mount /api/v1 before the contract freezes
Closed
#238 TopBar primaryAction button is inert on every screen except SchedulesScreen
Closed
#253 Replace-all PUTs have no optimistic concurrency — stale two-tab overwrite; define a shared If-Match/version contract before more editors ossify
Closed
#265 If-Match parsing: return 412 (not 400) for syntactically-valid but non-matching entity-tags (RFC 7232 semantics)
Closed
#319 Set security response headers (CSP, X-Content-Type-Options, Permissions-Policy, COEP) on the host — ZAP baseline finding (#314 / #197 input)
Closed
#301 #295: side-effecting GET endpoints bypass the session CSRF gate (troubleshoot playback/archive) — resolve with the SPA session cutover (PR2)
Closed
#295 [PLAN-MODE] Browser SPA auth = OIDC + local login (session); demote API key to external/MCP-only — revise Bundle A posture
Closed
#315 Release path: migration-on-prod-copy smoke (restore backup → apply migrations → boot) before promoting
Closed
#317 Merge-consent gate double-prompts on the satisfied path (exit-0 allow doesn't suppress the MCP prompt) — #303 H6/H10 follow-up
Closed
#303 Process hardening: queue-drift root-cause fix + methodology review + rigor-enforcement hooks
Closed
#311 Process hardening: enforce formatting-as-you-touch + rebase-before-push (H11 + PR-scoped format CI)
Closed
#312 Process hardening: H12 — session-end issue-qualification audit
Closed
#269 #253 follow-up: same-root config sibling writers don't rotate the aggregate ETag (cross-editor invalidation)
Closed
#271 External-collections scan has no status/progress REST surface — SPA collections buttons are optimistic + timeout-bounded
Closed
#287 #197 C2/C4/C5/C6 [BLOCKER/HIGH]: OpenAPI security scheme, 401/400 docs, operationIds, DayOfWeek — by construction
Closed
#288 #197 C3+C7 [HIGH]: DTO nullability noise + raw VMs + search pageNum before freeze
Closed
#289 #197 MCP [HIGH]: harden the read-only MCP server (runtime verb-guard, JSON-crash DoS, injection framing) — PR #76
Closed
#283 #197 S4+S9 [HIGH]: stored XSS via unvalidated upload content-type reflected on serve (supersedes #66)
Closed
#285 #197 S7+S10 [MED]: mutating GETs, spoofable ForwardedHeaders, scanner exemption, unpaged all-items
Closed
#284 #197 S6 [HIGH/MED]: CORS AllowAll — drive-by cross-origin reads/writes
Closed
#282 #197 S3+S5 [HIGH]: unauthenticated GETs leak private media samples, env vars, logs, settings, FS paths
Closed
#281 #197 S2 [HIGH]: persistent mutation outside /api bypasses the write key even when configured (SortController)
Closed
#280 #197 S1 [BLOCKER]: API writes are fail-OPEN by default — no key ⇒ every mutation unauthenticated
Closed
#66 Full image-type support for logo/watermark (incl. transparent re-encode)
Closed
#278 chore(release): ship v26.7.0 (Blazor removal) to prod + revert deploy model to :prod-following
Closed
#259 Replace-all reconcile: content-aware stable child identity (moved item inherits the wrong slot's state) — split from #253
Closed
#91 ChicoryTV SPA: Blazor → SPA cutover (retire old UI)
Closed
#235 Async-op API contract normalization + playout build observability (reviewer#20 F7+F8+F9)
Closed
#149 CI flake: migrations job MySQL service publishes fixed host port 3306 — concurrent runs collide
Closed
#254 Mutation hardening cluster (audit #21/#22/#23 low-severity): post-commit token consistency, orphan guide xml, child-id stability, dirty-nav guard, empty-list semantics
Closed
#257 Plex library-preferences save releases the library lock before the network scan runs (Unlock ordering)
Closed
#256 Media-source sign-out/disconnect handlers leak their EntityLocker on exception (no finally) — permanent 409
Closed
#255 Path-replacement UPDATE SQL is not source-scoped — a PUT to source A can overwrite source B's replacement
Closed
#202 Blazor removal blocked: media-source add/edit/path-replacement has NO SPA equivalent and NO write REST API
Closed
#205 Rollback: cut and document a dedicated pre-removal Blazor tag before deletion
Closed
#206 Removal plan has no auth step: deleting the last challenged Blazor page leaves only the open SPA
Closed
#204 Redirect matcher is exact-match only: parameterized legacy routes will hard-404 after Blazor deletion (Step 1 infeasible as written)
Closed
#251 Deco-template / deco edits don't invalidate dependent playouts — editor reports success but filler/break content stays stale until a manual Reset
Closed
#252 Schedule-items PUT cascade-deletes PlayoutScheduleItemFillGroupIndex — every save (even a no-op) silently resets fill-group progression
Closed
#234 Subtitle extraction leaks all playout locks on cancellation/exception; BuildPlayout ignores lock result (reviewer#20 F4+F5.2)
Closed
#233 Troubleshooting playback lock leaks permanently on "media not on disk"; lock conflict = 404 (reviewer#20 F3)
Closed
#244 Extract ChannelsScreen from App.tsx with colocated tests
Closed
#212 SPA channel editor gaps: external logo URL, bare-channel create, enumerated pickers downgraded to free-text
Closed
#230 Schedules editor dirty-draft guard gaps: popstate navigation + shuffle-toggle normalization
Closed
#231 [PLAN-MODE] EntityLocker soundness: atomic bool locks + ownership model (reviewer#20 F5)
Closed
#232 Scan lifecycle honesty: 200-on-dropped-scan, non-finally unlocks, unguarded enqueue (reviewer#20 F1+F2+F6)
Closed
#126 API: schedule item polymorphic fields rely on implicit Newtonsoft runtime-type serialization (OpenAPI schema gap)
Closed
#207 SPA schedules editor is read-only at mutation depth — create/edit/delete + per-item editing missing (blocks #91 phase b)
Closed
#215 API playout mutations skip EntityLocker build-lock gating (delete/reset/erase race with in-flight builds)
Closed
#213 Parity nits batch: block/watermark copy UI, trash select-all/see-all, logs sort, page-size persistence, stale UI notes, decision-log entries
Closed
#217 Add-items handlers validate existence for only 4 of 10 media kinds (collections + playlists)
Closed
#218 Sidebar shows stray "Playouts 3" badge (and "1 failing" health chip) on a fresh empty DB
Closed
#219 Per-show scan API can scan the wrong show because it resolves by substring title
Closed
#220 Episode cards remain inert despite search card-navigation parity claim
Closed
#221 Search and browse mutation controls can act on stale result sets during refetch
Closed
#236 CI: EF-migration mysql service publishes host port 3306 — concurrent jobs on one runner collide
Closed
#208 SPA search screen has no mutation surface: multi-select, add-to-collection/playlist, save-as-smart-collection, card navigation (blocks #91 phase b)
Closed
#209 SPA media browse/detail: add-to-* affordances, per-show scan, per-episode info/troubleshoot entries missing (blocks #91 phase b)
Closed
#211 SPA collections: custom playback order has no endpoint/UI; add-items picker covers 4 of 10 media kinds (blocks #91 phase b)
Closed
#210 SPA playouts: unwired delete/reset endpoints, missing erase-items/history + scheduling-context, templates preview calendar (blocks #91 phase b)
Closed
#203 Parity doc is unreliable as the deletion checklist: "SPA-READY" conflates screen-exists with functional parity
Closed
#198 OpenAPI spec property casing drifts from runtime JSON for leading-acronym fields (fFmpegProfileId vs ffmpegProfileId) — ChannelEditScreen silently mis-reads profile
Closed
#193 Harden rerun-collection create/update: existence-check the selected id
Closed
#145 SPA parity: Logs & troubleshooting pages (#91 blocker)
Closed
#153 API gap: playlists/playlist groups have no REST endpoints (blocks full #140 parity / #91)
Closed
#151 API gap: multi-collections have no REST endpoints (blocks full #140 parity / #91)
Closed
#152 API gap: rerun collections have no REST endpoints (blocks full #140 parity / #91)
Closed
#190 CI speed: cache NuGet packages (+ minor Docker/checkout wins)
Closed
#155 API gap: no endpoint lists a manual collection's items (GET /api/collections/{id}/items)
Closed
#184 ApiControllerSecurityTests registry has drifted: 9 controllers unlisted (2 with mutating verbs) — replace hardcoded array with assembly scanning
Closed
#185 Onboarding docs, part 2: testing map + generated endpoint index (HIGH PRIORITY, next session)
Closed
#141 SPA parity: Media browsing, search & trash (#91 blocker)
Closed
#161 API gap: media browse (all kinds), search, detail, delete, image folders (#141 blocker)
Closed
#158 API gap: logs + troubleshooting endpoints (#145 blocker)
Closed
#180 Channel Builder library picker: one tile per season floods the grid — group seasons under their show
Closed
#162 API gap: scheduling REST surface — blocks/decos/templates/deco-templates + playout create/detail editors (#144 blocker)
Closed
#144 SPA parity: Scheduling building blocks + playout detail editors (#91 blocker)
Closed
#157 Flaky web test: 'stops Libraries scan polling and refreshes sources once when scans complete' (App.test.tsx)
Closed
#160 API gap: Trakt lists controller (#142 blocker)
Closed
#142 SPA parity: Trakt lists (#91 blocker)
Closed
#159 API gap: filler preset + watermark editor CRUD; FFmpeg profile response DTO round-trip (#143 blocker)
Closed
#143 SPA parity: FFmpeg profiles, filler presets, watermarks editors (#91 blocker)
Closed
#140 SPA parity: Collections management screen (#91 blocker)
Closed
#146 SPA parity: Channel edit + channel numbers (#91 blocker)
Closed
#147 SPA: discoverable link to the legacy Blazor UI while parity gaps remain (#91 follow-up)
Closed
#90 ChicoryTV SPA: rebrand assets + naming
Closed
#93 ChicoryTV SPA: Settings screen (prototype → implement)
Closed
#92 Enable /design-sync round-trip (Claude Design ↔ repo, no zip)
Closed
#89 ChicoryTV SPA: Channel Builder (primary deliverable)
Closed
#63 Composite "create channel from lineup" endpoint
Closed
#64 Channel Templates (built-in + custom) bundling technical/behavioral defaults
Closed
#65 Library browse + search API with artwork (for the create-channel picker)
Closed
#85 ChicoryTV SPA: Guide / EPG screen
Closed
#88 ChicoryTV SPA: Libraries screen
Closed
#87 ChicoryTV SPA: Playouts screen
Closed
#86 ChicoryTV SPA: Schedule editor screen
Closed
#84 ChicoryTV SPA: Channels screen
Closed
#109 ChicoryTV SPA: Dashboard follow-up — replace stubbed data with real sources
Closed
#97 Backend: channel on-air / now-playing state API (for Channels screen live treatment)
Closed
#102 Backend: JSON channel-guide endpoint for the EPG grid
Closed
#111 Backend: schedule item duration estimates + schedule total
Closed
#104 Backend: logo/watermark image upload endpoint
Closed
#103 Backend: media sources + libraries read model (GET /api/media-sources)
Closed
#106 Backend: library scan status/progress endpoint
Closed
#101 Backend: GET /api/playouts/{id}/items endpoint
Closed
#107 Backend: playout build status + warnings count in the API
Closed
#110 Backend: playout reset-all endpoint + reset-mode reconciliation
Closed
#100 Backend: GET /api/playouts (list) endpoint
Closed
#108 Backend: expose health checks via REST (GET /api/health)
Closed
#105 Backend: list endpoints for filler presets, watermarks, graphics elements
Closed
#98 Backend: bulk channel operations API (renumber, move to group, bulk delete)
Closed
#96 Backend: extend channel list API for the management table (group, enabled, EPG visibility)
Closed
#95 Fix SPA foundation review findings (#78-#81 follow-up)
Closed
#94 Fix app-shell review findings (#82 follow-up)
Closed
#83 ChicoryTV SPA: Dashboard screen
Closed
#82 ChicoryTV SPA: app shell (sidebar + top bar + routing)
Closed
#81 ChicoryTV SPA: typed API client + auth
Closed
#80 ChicoryTV SPA: component library (primitives)
Closed
#79 ChicoryTV SPA: design tokens + 3 themes
Closed
#78 ChicoryTV SPA: scaffold + build integration
Closed
#3 CI/CD pipeline and test/prod environments
Closed
#57 chore: stop tracking local MCP config
Closed
#9 FFmpeg 8 compatibility (app-side) for transcode pipelines
Closed
#42 Implement Jellyfin MusicVideo library sync (currently silently dropped)
Closed
#43 API write-auth: decide a global default-deny model for all /api/* mutating endpoints
Closed
#39 test: make ChannelLogoGenerator testable (inject overlay/font paths) for a channel-logo property test
Closed
#2 Build REST API for channel/collection/schedule CRUD
Closed
#38 REST API #2e: Standardization cleanup (retrofit FFmpegProfileController, OpenAPI/CORS/docs)
Closed
#37 REST API #2d: Playouts create/delete
Closed
#36 REST API #2c: Schedules CRUD + schedule items (TPT-heavy)
Closed
#46 REST API: standardize error response body contract
Closed
#35 REST API #2b: Collections CRUD + items (+ retrofit SmartCollectionController)
Closed
#34 REST API #2a: API foundation + Channels CRUD (pattern-setter)
Closed
#24 2 PlayoutModeSchedulerBase filler tests fail under non-UTC local timezones
Closed
#28 Golden tests for XMLTV guide + channel-logo output (follow-up to #11)
Closed
#5 Jellyfin removes ErsatzTV items during library scan (MTV Unplugged)
Closed
#1 Fix M3U tvg-logo URLs hardcoding localhost
Closed
#10 Write a retroactive contributors / style guide capturing established patterns
Closed
#16 Container E2E: assert key IPTV endpoints on the built image
Closed
#13 CI checks for EF Core migration integrity (SQLite + MySql)
Closed
#11 Golden-file tests for M3U / XMLTV / channel-logo output
Closed
#12 Enforce architecture / layering with tests
Closed
#8 Update vulnerable transitive dependencies (NuGet audit advisories)
Closed
#14 Dependency hygiene: scheduled vulnerability scan + Central Package Management
Closed
#4 Set up Gitea Actions Docker build workflow
Closed
#7 Slim memory files — move reference content to in-repo docs
Closed
#6 Missing architecture docs: channel management, M3U generation, logo fixes
470 Issues created by 2 users
Opened
#1 Fix M3U tvg-logo URLs hardcoding localhost
Opened
#2 Build REST API for channel/collection/schedule CRUD
Opened
#3 CI/CD pipeline and test/prod environments
Opened
#4 Set up Gitea Actions Docker build workflow
Opened
#5 Jellyfin removes ErsatzTV items during library scan (MTV Unplugged)
Opened
#6 Missing architecture docs: channel management, M3U generation, logo fixes
Opened
#7 Slim memory files — move reference content to in-repo docs
Opened
#8 Update vulnerable transitive dependencies (NuGet audit advisories)
Opened
#9 FFmpeg 8 compatibility (app-side) for transcode pipelines
Opened
#10 Write a retroactive contributors / style guide capturing established patterns
Opened
#11 Golden-file tests for M3U / XMLTV / channel-logo output
Opened
#12 Enforce architecture / layering with tests
Opened
#13 CI checks for EF Core migration integrity (SQLite + MySql)
Opened
#14 Dependency hygiene: scheduled vulnerability scan + Central Package Management
Opened
#15 Adopt a C# lint/format/static-analysis stack (the ruff equivalent) and enforce in CI
Opened
#16 Container E2E: assert key IPTV endpoints on the built image
Opened
#22 Dependency Dashboard
Opened
#24 2 PlayoutModeSchedulerBase filler tests fail under non-UTC local timezones
Opened
#25 Burn down SonarAnalyzer findings in Blazor .razor (analyzer adoption #15)
Opened
#28 Golden tests for XMLTV guide + channel-logo output (follow-up to #11)
Opened
#34 REST API #2a: API foundation + Channels CRUD (pattern-setter)
Opened
#35 REST API #2b: Collections CRUD + items (+ retrofit SmartCollectionController)
Opened
#36 REST API #2c: Schedules CRUD + schedule items (TPT-heavy)
Opened
#37 REST API #2d: Playouts create/delete
Opened
#38 REST API #2e: Standardization cleanup (retrofit FFmpegProfileController, OpenAPI/CORS/docs)
Opened
#39 test: make ChannelLogoGenerator testable (inject overlay/font paths) for a channel-logo property test
Opened
#42 Implement Jellyfin MusicVideo library sync (currently silently dropped)
Opened
#43 API write-auth: decide a global default-deny model for all /api/* mutating endpoints
Opened
#46 REST API: standardize error response body contract
Opened
#57 chore: stop tracking local MCP config
Opened
#58 Backlog: MCP server for ErsatzTV/ChicoryTV API
Opened
#59 Backlog: full UI redesign and ChicoryTV rebrand
Opened
#60 Backlog: browser channel playback after UI redesign
Opened
#62 Epic: Create Channel — backend prerequisites for the redesigned creation flow
Opened
#63 Composite "create channel from lineup" endpoint
Opened
#64 Channel Templates (built-in + custom) bundling technical/behavioral defaults
Opened
#65 Library browse + search API with artwork (for the create-channel picker)
Opened
#66 Full image-type support for logo/watermark (incl. transparent re-encode)
Opened
#67 Unified logo/bug image handling (one image drives both, separable)
Opened
#68 Resume/bookmark playback position for sequential channels (personal continue-watching)
Opened
#69 Auto-tuning: generate channels automatically from library metadata
Opened
#70 Weighted / fair-share content distribution (playback order)
Opened
#71 Persistent shuffle state + explicit "Reroll" control
Opened
#72 Channel lineup health at-a-glance (status states in the channels list)
Opened
#73 Seasonal / date-conditional channels & schedule rules
Opened
#74 [Blue sky] On-screen "On Now / On Next" overlay (channel-surf bug)
Opened
#75 [Blue sky] Themed "Resource Packs" for bumpers / branding / interstitials
Opened
#77 Pad/snap channel schedules to clock boundaries (:00/:15/:30) using filler
Opened
#78 ChicoryTV SPA: scaffold + build integration
Opened
#79 ChicoryTV SPA: design tokens + 3 themes
Opened
#80 ChicoryTV SPA: component library (primitives)
Opened
#81 ChicoryTV SPA: typed API client + auth
Opened
#82 ChicoryTV SPA: app shell (sidebar + top bar + routing)
Opened
#83 ChicoryTV SPA: Dashboard screen
Opened
#84 ChicoryTV SPA: Channels screen
Opened
#85 ChicoryTV SPA: Guide / EPG screen
Opened
#86 ChicoryTV SPA: Schedule editor screen
Opened
#87 ChicoryTV SPA: Playouts screen
Opened
#88 ChicoryTV SPA: Libraries screen
Opened
#89 ChicoryTV SPA: Channel Builder (primary deliverable)
Opened
#90 ChicoryTV SPA: rebrand assets + naming
Opened
#91 ChicoryTV SPA: Blazor → SPA cutover (retire old UI)
Opened
#92 Enable /design-sync round-trip (Claude Design ↔ repo, no zip)
Opened
#93 ChicoryTV SPA: Settings screen (prototype → implement)
Opened
#94 Fix app-shell review findings (#82 follow-up)
Opened
#95 Fix SPA foundation review findings (#78-#81 follow-up)
Opened
#96 Backend: extend channel list API for the management table (group, enabled, EPG visibility)
Opened
#97 Backend: channel on-air / now-playing state API (for Channels screen live treatment)
Opened
#98 Backend: bulk channel operations API (renumber, move to group, bulk delete)
Opened
#99 Backend: track active sessions for MPEG-TS and HLS-Direct streams
Opened
#100 Backend: GET /api/playouts (list) endpoint
Opened
#101 Backend: GET /api/playouts/{id}/items endpoint
Opened
#102 Backend: JSON channel-guide endpoint for the EPG grid
Opened
#103 Backend: media sources + libraries read model (GET /api/media-sources)
Opened
#104 Backend: logo/watermark image upload endpoint
Opened
#105 Backend: list endpoints for filler presets, watermarks, graphics elements
Opened
#106 Backend: library scan status/progress endpoint
Opened
#107 Backend: playout build status + warnings count in the API
Opened
#108 Backend: expose health checks via REST (GET /api/health)
Opened
#109 ChicoryTV SPA: Dashboard follow-up — replace stubbed data with real sources
Opened
#110 Backend: playout reset-all endpoint + reset-mode reconciliation
Opened
#111 Backend: schedule item duration estimates + schedule total
Opened
#126 API: schedule item polymorphic fields rely on implicit Newtonsoft runtime-type serialization (OpenAPI schema gap)
Opened
#135 from-lineup advanced overrides cannot express "clear to none" (null = inherit template)
Opened
#140 SPA parity: Collections management screen (#91 blocker)
Opened
#141 SPA parity: Media browsing, search & trash (#91 blocker)
Opened
#142 SPA parity: Trakt lists (#91 blocker)
Opened
#143 SPA parity: FFmpeg profiles, filler presets, watermarks editors (#91 blocker)
Opened
#144 SPA parity: Scheduling building blocks + playout detail editors (#91 blocker)
Opened
#145 SPA parity: Logs & troubleshooting pages (#91 blocker)
Opened
#146 SPA parity: Channel edit + channel numbers (#91 blocker)
Opened
#147 SPA: discoverable link to the legacy Blazor UI while parity gaps remain (#91 follow-up)
Opened
#149 CI flake: migrations job MySQL service publishes fixed host port 3306 — concurrent runs collide
Opened
#151 API gap: multi-collections have no REST endpoints (blocks full #140 parity / #91)
Opened
#152 API gap: rerun collections have no REST endpoints (blocks full #140 parity / #91)
Opened
#153 API gap: playlists/playlist groups have no REST endpoints (blocks full #140 parity / #91)
Opened
#155 API gap: no endpoint lists a manual collection's items (GET /api/collections/{id}/items)
Opened
#157 Flaky web test: 'stops Libraries scan polling and refreshes sources once when scans complete' (App.test.tsx)
Opened
#158 API gap: logs + troubleshooting endpoints (#145 blocker)
Opened
#159 API gap: filler preset + watermark editor CRUD; FFmpeg profile response DTO round-trip (#143 blocker)
Opened
#160 API gap: Trakt lists controller (#142 blocker)
Opened
#161 API gap: media browse (all kinds), search, detail, delete, image folders (#141 blocker)
Opened
#162 API gap: scheduling REST surface — blocks/decos/templates/deco-templates + playout create/detail editors (#144 blocker)
Opened
#163 Golden-style characterization tests for playout building
Opened
#164 Health checks UX: audit usefulness + guided/automated remediation
Opened
#172 Scheduling API hardening follow-ups from #144 S1/S2 reviews
Opened
#176 Rethink channel/playout/schedule creation: PseudoTV-style channel-first flow with a Kodi-smart-playlist-like query builder
Opened
#177 Jellyfin music video sync: map Album/Track metadata (credits-overlay completeness)
Opened
#178 Idea (far future): Jellyfin plugin to control ErsatzTV from within Jellyfin
Opened
#180 Channel Builder library picker: one tile per season floods the grid — group seasons under their show
Opened
#184 ApiControllerSecurityTests registry has drifted: 9 controllers unlisted (2 with mutating verbs) — replace hardcoded array with assembly scanning
Opened
#185 Onboarding docs, part 2: testing map + generated endpoint index (HIGH PRIORITY, next session)
Opened
#190 CI speed: cache NuGet packages (+ minor Docker/checkout wins)
Opened
#193 Harden rerun-collection create/update: existence-check the selected id
Opened
#197 Cold adversarial review: REST API contract + security posture (pre-ossification)
Opened
#198 OpenAPI spec property casing drifts from runtime JSON for leading-acronym fields (fFmpegProfileId vs ffmpegProfileId) — ChannelEditScreen silently mis-reads profile
Opened
#202 Blazor removal blocked: media-source add/edit/path-replacement has NO SPA equivalent and NO write REST API
Opened
#203 Parity doc is unreliable as the deletion checklist: "SPA-READY" conflates screen-exists with functional parity
Opened
#204 Redirect matcher is exact-match only: parameterized legacy routes will hard-404 after Blazor deletion (Step 1 infeasible as written)
Opened
#205 Rollback: cut and document a dedicated pre-removal Blazor tag before deletion
Opened
#206 Removal plan has no auth step: deleting the last challenged Blazor page leaves only the open SPA
Opened
#207 SPA schedules editor is read-only at mutation depth — create/edit/delete + per-item editing missing (blocks #91 phase b)
Opened
#208 SPA search screen has no mutation surface: multi-select, add-to-collection/playlist, save-as-smart-collection, card navigation (blocks #91 phase b)
Opened
#209 SPA media browse/detail: add-to-* affordances, per-show scan, per-episode info/troubleshoot entries missing (blocks #91 phase b)
Opened
#210 SPA playouts: unwired delete/reset endpoints, missing erase-items/history + scheduling-context, templates preview calendar (blocks #91 phase b)
Opened
#211 SPA collections: custom playback order has no endpoint/UI; add-items picker covers 4 of 10 media kinds (blocks #91 phase b)
Opened
#212 SPA channel editor gaps: external logo URL, bare-channel create, enumerated pickers downgraded to free-text
Opened
#213 Parity nits batch: block/watermark copy UI, trash select-all/see-all, logs sort, page-size persistence, stale UI notes, decision-log entries
Opened
#215 API playout mutations skip EntityLocker build-lock gating (delete/reset/erase race with in-flight builds)
Opened
#217 Add-items handlers validate existence for only 4 of 10 media kinds (collections + playlists)
Opened
#218 Sidebar shows stray "Playouts 3" badge (and "1 failing" health chip) on a fresh empty DB
Opened
#219 Per-show scan API can scan the wrong show because it resolves by substring title
Opened
#220 Episode cards remain inert despite search card-navigation parity claim
Opened
#221 Search and browse mutation controls can act on stale result sets during refetch
Opened
#230 Schedules editor dirty-draft guard gaps: popstate navigation + shuffle-toggle normalization
Opened
#231 [PLAN-MODE] EntityLocker soundness: atomic bool locks + ownership model (reviewer#20 F5)
Opened
#232 Scan lifecycle honesty: 200-on-dropped-scan, non-finally unlocks, unguarded enqueue (reviewer#20 F1+F2+F6)
Opened
#233 Troubleshooting playback lock leaks permanently on "media not on disk"; lock conflict = 404 (reviewer#20 F3)
Opened
#234 Subtitle extraction leaks all playout locks on cancellation/exception; BuildPlayout ignores lock result (reviewer#20 F4+F5.2)
Opened
#235 Async-op API contract normalization + playout build observability (reviewer#20 F7+F8+F9)
Opened
#236 CI: EF-migration mysql service publishes host port 3306 — concurrent jobs on one runner collide
Opened
#237 ChicoryTV rewrite — queue tracker (goal, arc, session protocol)
Opened
#238 TopBar primaryAction button is inert on every screen except SchedulesScreen
Opened
#243 Refactor ChicoryTV App.tsx into screen-owned modules and a small app shell
Opened
#244 Extract ChannelsScreen from App.tsx with colocated tests
Opened
#245 Extract PlayoutsScreen and playout UI helpers from App.tsx
Opened
#246 Extract Dashboard and Guide screens from App.tsx
Opened
#247 Extract ChicoryTV shell/routing and replace implicit TopBar action coupling
Opened
#248 SPA dialogs (overlay.tsx) are not focus-trapped / background-inerted
Opened
#251 Deco-template / deco edits don't invalidate dependent playouts — editor reports success but filler/break content stays stale until a manual Reset
Opened
#252 Schedule-items PUT cascade-deletes PlayoutScheduleItemFillGroupIndex — every save (even a no-op) silently resets fill-group progression
Opened
#253 Replace-all PUTs have no optimistic concurrency — stale two-tab overwrite; define a shared If-Match/version contract before more editors ossify
Opened
#254 Mutation hardening cluster (audit #21/#22/#23 low-severity): post-commit token consistency, orphan guide xml, child-id stability, dirty-nav guard, empty-list semantics
Opened
#255 Path-replacement UPDATE SQL is not source-scoped — a PUT to source A can overwrite source B's replacement
Opened
#256 Media-source sign-out/disconnect handlers leak their EntityLocker on exception (no finally) — permanent 409
Opened
#257 Plex library-preferences save releases the library lock before the network scan runs (Unlock ordering)
Opened
#259 Replace-all reconcile: content-aware stable child identity (moved item inherits the wrong slot's state) — split from #253
Opened
#264 Local libraries always show "Never scanned" — local scanner sets path-level LastScan but not library.LastScan
Opened
#265 If-Match parsing: return 412 (not 400) for syntactically-valid but non-matching entity-tags (RFC 7232 semantics)
Opened
#269 #253 follow-up: same-root config sibling writers don't rotate the aggregate ETag (cross-editor invalidation)
Opened
#271 External-collections scan has no status/progress REST surface — SPA collections buttons are optimistic + timeout-bounded
Opened
#278 chore(release): ship v26.7.0 (Blazor removal) to prod + revert deploy model to :prod-following
Opened
#280 #197 S1 [BLOCKER]: API writes are fail-OPEN by default — no key ⇒ every mutation unauthenticated
Opened
#281 #197 S2 [HIGH]: persistent mutation outside /api bypasses the write key even when configured (SortController)
Opened
#282 #197 S3+S5 [HIGH]: unauthenticated GETs leak private media samples, env vars, logs, settings, FS paths
Opened
#283 #197 S4+S9 [HIGH]: stored XSS via unvalidated upload content-type reflected on serve (supersedes #66)
Opened
#284 #197 S6 [HIGH/MED]: CORS AllowAll — drive-by cross-origin reads/writes
Opened
#285 #197 S7+S10 [MED]: mutating GETs, spoofable ForwardedHeaders, scanner exemption, unpaged all-items
Opened
#286 #197 C1 [BLOCKER]: no API versioning — mount /api/v1 before the contract freezes
Opened
#287 #197 C2/C4/C5/C6 [BLOCKER/HIGH]: OpenAPI security scheme, 401/400 docs, operationIds, DayOfWeek — by construction
Opened
#288 #197 C3+C7 [HIGH]: DTO nullability noise + raw VMs + search pageNum before freeze
Opened
#289 #197 MCP [HIGH]: harden the read-only MCP server (runtime verb-guard, JSON-crash DoS, injection framing) — PR #76
Opened
#293 Page/cap GET /api/search/all-items (DoS hardening — deferred from #285)
Opened
#295 [PLAN-MODE] Browser SPA auth = OIDC + local login (session); demote API key to external/MCP-only — revise Bundle A posture
Opened
#297 Add channelId to PlayoutListItemResponseModel so the SPA reset button keys directly
Opened
#299 CI: codify the manual live-E2E flows into an automated functional-E2E harness
Opened
#301 #295: side-effecting GET endpoints bypass the session CSRF gate (troubleshoot playback/archive) — resolve with the SPA session cutover (PR2)
Opened
#303 Process hardening: queue-drift root-cause fix + methodology review + rigor-enforcement hooks
Opened
#308 Concurrent same-item Add*ToCollection can 500 on composite-PK violation (pre-existing idempotency-under-concurrency gap)
Opened
#310 De-BOM the 17 legacy .cs files #269 touched (charset=utf-8 violation)
Opened
#311 Process hardening: enforce formatting-as-you-touch + rebase-before-push (H11 + PR-scoped format CI)
Opened
#312 Process hardening: H12 — session-end issue-qualification audit
Opened
#314 Out-of-ecosystem black-box security scan against the running container (#197 exit criterion)
Opened
#315 Release path: migration-on-prod-copy smoke (restore backup → apply migrations → boot) before promoting
Opened
#317 Merge-consent gate double-prompts on the satisfied path (exit-0 allow doesn't suppress the MCP prompt) — #303 H6/H10 follow-up
Opened
#319 Set security response headers (CSP, X-Content-Type-Options, Permissions-Policy, COEP) on the host — ZAP baseline finding (#314 / #197 input)
Opened
#320 TroubleshootController playback segment-wait loop doesn't check notifier.IsFailed (spins until client cancel if ffmpeg dies)
Opened
#327 Playlist rename (ReplacePlaylistItems) does no name validation — empty / >50-char names accepted
Opened
#330 Add Cross-Origin-Resource-Policy header (ZAP #314 authenticated-scan Low)
Opened
#332 docs: make ChicoryTV queue handoff client-neutral
Opened
#333 test: run #202 real-server media-source integration validation
Opened
#334 security: keep local-library filesystem paths authenticated when reads are open
Opened
#335 release: cut v26.8.0 and complete ChicoryTV go-live
Opened
#336 docs: prepare the v26.8.0 release boundary
Opened
#338 ci: distinguish ZAP warning exit 2 from FAIL in security-scan
Opened
#339 docs: require low-cost queue selection preflight
Opened
#340 Add configurable advertised IPTV base URL for M3U/XMLTV output
Opened
#342 Enforce session-wide low-cost routing for bounded reconnaissance
Opened
#344 Saving a remote connection falsely triggers the dirty guard
Opened
#345 Plex pin flow reports connected but strands authorized accounts with no servers
Opened
#347 Queue selector skips milestone work and repicks completed reviewer audits
Opened
#350 Channel cold-start ~7s to first segment — slow tune-in via Dispatcharr/Kodi (heavy transcode profile)
Opened
#353 docs: start tool-bearing selectors at low effort
Opened
#354 ChicoryTV: subtitles progressively run ahead of dialogue during playback
Opened
#355 docs: record tested Codex cheap-worker launch configuration
Opened
#357 Jellyfin/Kodi PoC: player-owned channel playback with ErsatzTV as channel engine
Opened
#363 functional-E2E harness: add the deferred media/lock/Playwright flows (follow-up to #299)
Opened
#364 docs: make queue selection non-terminal
Opened
#367 Plex: budget-exhausted message says "Use Refresh" but there is no global Refresh when zero servers exist
Opened
#373 bug(spa): white border around the edges of the login / boot pages (missing body margin reset)
Opened
#376 XMLTV: access_token query value interpolated raw into guide (pre-existing XML-injection)
Opened
#377 SPA: left sidebar scrolls horizontally (unwanted overflow-x)
Opened
#380 Refactor: shared enumerator-construction/state seam for PlaybackOrder across scheduling engines
Opened
#381 Golden characterization tests for remaining scheduler kinds (Sequential YAML + Scripted)
Opened
#383 Auto-Tune: per-channel configuration (DetailPanel) — editable per-channel step
Opened
#384 Auto-Tune DetailPanel: enumerate a SmartCollection's distinct members (read endpoint)
Opened
#385 Auto-Tune DetailPanel: per-channel overrides + rotation weights in bulk-create
Opened
#386 Auto-Tune DetailPanel: per-channel editor slide-over (SPA)
Opened
#388 Mirror the ChicoryTV design system to prod (Claude Design ↔ shipped SPA)
Opened
#390 CI: shared toolchain base image (.NET 10 SDK + Node 22 + ffmpeg) for CI jobs
Opened
#392 Clock-align convenience: one-click per-channel/schedule pad-to-boundary toggle + 60-min increment (SPA)
Opened
#395 Refactor: dedup Scripted≡YAML enumerator construction (deferred from #380, gated on #381 goldens)
Opened
#396 Collapsible left sidebar + collapsible nav groups
Opened
#398 CI: build once, reuse artifacts across test / migrations / functional-e2e (742s of redundant compilation per run)
Opened
#401 UpdateChannel silently coerces Mirror→Generated when the channel has a playout (should be 422)
Opened
#403 Scheduling: an unhandled PlaybackOrder fails silently at five of six dispatch sites
Opened
#404 SPA: per-source weight inputs + fair-share toggle in the schedule editor (#70 UI)
Opened
#406 CI: cut peak build RSS (Roslyn), cap the services: mysql, and move api-docs/format back to ubuntu-latest
Opened
#409 Never-scanned local libraries render "Last scan 12:00 AM" instead of "Never scanned" (LastScan seeded as DateTime.MinValue, not NULL)
Opened
#410 Scan cancellation is logged at ERROR ("Scan was canceled") across all four scan handlers
Opened
#412 CI: peak-memory instrument reports cache-inflated memory.peak; sample true peak anon instead
Opened
#414 Channels list: distinguish auto-tuned from user-created channels (origin marker)
Opened
#415 Per-channel fault detection beyond "no playout" (empty schedule, broken source)
Opened
#416 CI: docs-only changes run the full build/test matrix (~9 min) for nothing
Opened
#420 CI: PR run and merge-to-main run re-execute the full matrix over identical code
Opened
#421 M3U: access_token value not quote-safe in url-tvg="..." attribute
Opened
#425 Auto-Tune DetailPanel: per-source rotation weights + query corrections (weighted-distribution redesign)
Opened
#431 Backend: TTL-cache PerformHealthChecks (GET /api/v1/health re-runs 14 checks, 4 shell out to ffmpeg, per request)
Opened
#434 Rule builder: facet-value typeahead for text fields (#176 follow-up)
Opened
#435 Rule builder: relative-date operators ("in the last N days") (#176 follow-up)
Opened
#436 Rule builder: support nesting deeper than one level (#176 follow-up)
Opened
#437 Adopt RuleBuilder inline in ChannelBuilder & Auto-Tune (#176 follow-up)
Opened
#438 Rule builder: input validation & polish (bundles #176 review minors)
Opened
#440 Auto-Tune DetailPanel SPA: wire per-source weight steppers + exclude/add-untagged to the #425 backend
Opened
#444 functional-E2E: add the playout-build lock 409 + isLocked projection flow (deferred from #363)
Opened
#445 functional-E2E: add the UI-interactive Playwright (headless) flows (deferred from #363)
Opened
#447 Flaky SPA test: LibrariesScreen "stops scan polling and refreshes sources once when scans complete"
Opened
#458 Playlist/group rename should reject duplicate names (like create does) — #327 follow-up
Opened
#460 MediaSourceRepository writes MinValue LastScan on disable-sync — normalize to null (#409 follow-up)
Opened
#463 Schedules screen: "Active schedule" selector stretches full-width and overlaps the header
Opened
#464 Guide + channels list show generated fallback icons instead of the actual channel logo
Opened
#469 CI: speed up the Formatting job (dotnet format --include still loads the whole solution)
Opened
#472 Split HLS cold-start startup phase into spawn / input-open+probe / first-GOP
Opened
#473 Tune-in hard-fails (ffmpeg exit 8) when a playout item's media file no longer exists — 717 stale episodes across 10 removed shows on prod
Opened
#474 Music channels dead: Music Videos library has no LibraryPath, so /data/music (30 folders) is never scanned — 8+ collections empty
Opened
#476 Scanner: FileNotFound does not cascade show → seasons → episodes, so playouts keep scheduling episodes of shows deleted upstream
Opened
#477 Scanner has no anti-nuke guard: a successful-but-empty media-server fetch flags an entire library FileNotFound
Opened
#478 Channels 102/107 repeatedly fail to tune: h264_vaapi hwupload -22 / exit 234 on prod
Opened
#480 External-JSON playout channels still hand ffmpeg an unprobed remote-stream URL (#473 class survives there)
Opened
#484 Media-server scanner: ratio-threshold + projection-failure detection for the empty-fetch guard
Opened
#485 Build hygiene: .gitignore core entry silently ignores new files under any Core/ directory (case-insensitive on macOS)
Opened
#487 MCP acceptance case: populate the empty music collections via the MCP write path (not by hand)
Opened
#488 JellyfinMusicVideoLibraryScanner crashes immediately: ArgumentNullException from null LibraryPath.LibraryFolders (feature has never worked)
Opened
#489 Support Jellyfin mixed-content libraries (currently dropped silently) — keep music/standup segregated from Movies & TV Shows
Opened
#491 LibraryFolder has no unique index on (LibraryPathId, Path) — concurrent GetOrAddFolder can insert duplicates
Opened
#494 JellyfinMusicVideoLibraryScanner does no reconciliation — music videos removed from Jellyfin are never removed from ErsatzTV
Opened
#496 Music videos have no per-library identity — global GetOrAdd path dedup can cross-library false-trash
Opened
#497 JellyfinMusicVideoLibraryScanner.UpdateMetadata drops Tags/Genres/Studios on existing items — Jellyfin metadata edits never sync
Opened
#498 FFmpeg profile should allow separate decode and encode hardware acceleration (QSV encode + VAAPI decode)
Opened
#500 MediaServer metadata reconcile double-inserts on duplicate collection names (Plex movie + Jellyfin music-video update paths)
Opened
#502 External-URL channel logos never render an on-screen bug (File.Exists against a URL in WatermarkSelector)
Opened
#503 Watermark MiddleCenter renders bottom-right — missing switch arm in OverlayWatermarkFilter
Opened
#505 QSV native-decode path tonemaps HDR in software (route through tonemap_qsv)
Opened
#508 Move the two docker build jobs off the small runner lane
Opened
#510 WatermarkSelector: the deco path has a different missing-logo policy than the three precedence levels
Opened
#511 Harden remote-image fetching in the graphics engine (timeout, size cap, redirects, pooling, caching, SSRF)
Opened
#512 Make LibrariesScreen scan-complete test deterministic (stop racing real microtasks under waitFor)
Opened
#515 release: cut and promote v26.11.0 to prod (first release on jazz)
Opened
#519 Verify the #350 cold-start burst end-to-end on test, then re-measure on prod
Opened
#520 Retire #237 from startup; run orientation and mechanical top-five selection in parallel
Opened
#521 Make decision knowledge lifecycle-addressable and retrieval-efficient
Opened
#523 QSV native-decode (#498) hwupload fails to allocate a QSV surface for certain content — "Cannot allocate memory" kills the stream
Opened
#524 Retrofit #237's durable-only facts into #521 decision records (post-arc follow-up)
Opened
#525 External channel-logo URLs: download + cache at save time instead of fetching at render time
Opened
#529 QSV extra_hw_frames=0 kills transcodes on any unthrottled read — live in prod, and made near-deterministic by #516's burst
Opened
#532 Re-measure HLS cold start on prod after v26.12.0+ ships the #529 floor, against #350's 13-sample baseline
Opened
#533 scripts/e2e-local.sh readiness probe hangs on a reused config dir
Opened
#535 Release-tag builds: small-lane PR-only gate jobs run + fail on v* tag pushes
Opened
#536 workAheadSegmenterLimit is not enforced: the slot check and its increment straddle an await (N concurrent tune-ins all run unthrottled)
Opened
#539 WorkAheadSlots.Release hardening: never go negative, and surface UnbalancedReleases somewhere a human will see it
Opened
#541 H13: session-end must leave the shared checkout fresh — a stale tree serves stale FILES, which no HEAD-reading rule catches
Opened
#542 The kickoff handoff doc should be instructions, not incident history — prune the narrative into decisions.md
Opened
#545 decisions-guard: require a **Signals:** line (MemPalace recall metadata contract)
Opened
#548 docs: the ersatztv skill described archived upstream, not this fork
Opened
#552 Mint a short-lived JWT for the SPA so /iptv/* works under JWT-enabled deployments
Opened
#553 select-queue.sh ranks Renovate's bot-authored Dependency Dashboard (#22) as a workable pickup
Opened
#554 Channel preview can sit at "starting" when autoplay is blocked, with no hint to press play
Opened
#559 Harden the /iptv ?access_token= transport: redact from request logs + no-store on tokened manifests
Opened
#563 Scripted playout: integration-test harness (deferred from #381 golden net)
Opened
#565 [Blue sky] Bridge Auto-Tune → Scripted: an "escape hatch" from a generated channel into a custom script
Opened
#567 Harden channel graphicsElementIds: validate unknown ids (422 not 500) + builtIn discriminator (#74 follow-up)
Opened
#568 Harden channel graphicsElementIds: validate unknown ids (422 not 500) + builtIn discriminator (#74 follow-up)
Opened
#570 On Now/Next overlay YAML fails to render (format_datetime arity + null font_family) — #74 hotfix
Opened
#572 CustomFontMapper crashes on a null font_family instead of using the default font
Opened
#578 #434 follow-ups: typeahead combobox polish + source limitations
Opened
#580 Auto-Tune: generalize the fixed axis picker into an arbitrary group-by field builder (backend, #437 split)
Opened
#582 flaky: LibrariesScreen "stops scan polling and refreshes sources once when scans complete" still non-deterministic (#512 fix incomplete)
Opened
#583 Kickoff: make per-agent model routing a hard constraint + a PreToolUse gate
Opened
#586 E2E briefs: scope process cleanup by PID, never a pattern-wide pkill
Opened
#587 chore(docs): trim derivable content from CLAUDE.md and lazy-load the task-completion protocol
Opened
#590 Auto-Tune source rows: share the Lucene escaper, warn on exclude-all, handle >50-source axes
Opened
#592 CI monitors: record that skipped is not red (build skips on every PR)
Opened
#594 ci-image-pin accepts any hex length, not the exact 7-char tag ci-image.yml publishes
Opened
#595 Active decisions corpus is at its 5600-line budget — schedule the consolidation
Opened
#596 PID-scope the Playwright-MCP stall recovery — pkill -f ms-playwright-mcp is the same shared-host reap as #586
Opened
#597 ci-image.yml should tag with --short=7 so the 7-char pin length is an enforced invariant, not an observed one
Opened
#600 Remove-stale + add-new reconcile idiom: 8 further copies still double-insert on duplicate names (#500 follow-up)
Opened
#603 decisions: adopt OKF's stale-after and Sources: as optional record metadata
Opened
#604 Collection membership rebuild has no projection-failure guard — a swallowed drop silently empties a collection
Opened
#606 One MediaItem row per file path globally — a second library serving the same file never gets its own row
Opened
#608 GetParentFolderId bypasses GetFolder — case-insensitive parent resolution can distort the folder tree on MySQL
Opened
#609 decisions-validate: [decisions-edit] is a bare substring match — a commit that merely *describes* the token disarms the guard
Opened
#610 decisions: split the monolithic corpus into one YAML-frontmatter file per record
Opened
#615 Jellyfin merges <Base> - <variant>.mp4 music videos into one multi-version item — Behind the Music (61 files) and Top of the Pops (24 files) each land as a single ErsatzTV item
Opened
#616 MCP/API paging traps: pageNum documented 1-based but is 0-based, pageSize cap doesn't clamp the offset, and playout rows carry no channelId
Opened
#617 .claude/skills/jellyfin/ is a stale divergent copy, not the symlink CLAUDE.md describes — it documents auth that v12 only accepts by legacy opt-in
Opened
#620 decisions corpus consolidation has no owner — and after #610 the budget number stops reporting it
Opened
#621 decisions: a record file that fails to parse is silently invisible — no structural "one keyed record per file" check
Opened
#622 merge gate: docs-only exemption is computed from a TRUNCATED file list (confirmed); auto-merge scheduling also freezes H10 consent (structural)
Opened
#627 Re-arm the MySQL data-migration fixture in CI — the dedupe DML has no automated coverage on MySQL
Opened
#629 merge gate: false-opens in the H10 verdict classifier — an undefined token, code blocks (fenced/indented/HTML), a URL-borne sha, and a read path that failed open
Opened
#631 scripts/tests/ is never executed by CI — the Python test suite is local-only
Opened
#632 A PR base change leaves the head sha — and so the review-verdict/h10 status — unchanged
Opened
#633 OpenAPI pageNum parameters carry no description, so the 0-based contract is invisible to REST consumers
Opened
#634 Rerun-collection picker in SchedulesScreen silently truncates at 100 (asks for pageSize 1000, server clamps to 100)
Opened
#640 ~25 music-video files are on disk but never ingested by Jellyfin — 4 folders short of their file count (not multi-version merging)
Opened
#643 Merge-consent gate fails OPEN on jq 1.6: a transport failure mid-pagination lets the docs-only exemption fire over a PARTIAL file list
Opened
#644 Seven more SPA list loads silently truncate at the server cap (same class as #634, one screen over)
Opened
#647 H10 verdict classifier is inert on jq 1.6: contains("�") matches every string, and a parse error is indistinguishable from an empty list
Opened
#648 Pin or preflight jq in CI: the runner ships 1.6, dev machines ship 1.8.x, and that gap silently broke three shell gates
Opened
#649 The ENFORCED review-verdict.yml guard is weaker than the advisory local hook — duplicated security logic has drifted
Opened
#650 Two more list loads truncate at the cap — but at-cap, so #644's over-cap grep could not see them
Opened
#651 Library-browse pickers need a searchable source, not a 100-row window or a full-library crawl
Opened
#652 Revive the generated-initials logo bug by caching it, not by fetching it at render time
Opened
#653 Song-progress overlay bypasses WatermarkSelector and can hand ffmpeg a nonexistent -i path
Opened
#660 Anamorphic HDR sources are excluded from the QSV OpenCL tonemap (runtime sar vs calculated SAR)
Opened
#661 HardwareUploadVaapiFilter(setFormat, deriveDevice = false) — a defaulted bool that silently strands frames on the wrong device
Opened
#662 Typeahead artist suggestions miss free-text credits; album_artist 404s — value-converted list columns have no suggestion source
Opened
#663 A review-verdict/h10 success is repo-global, so a second PR with the same head inherits it
Opened
#664 pr-changed-files.sh head binding cannot see an A→B→A force-push across its paging round-trips
Opened
#665 ChannelBuilder library-browse "Load more": cross-page sort order and an overclaimed totalCount permit no-op requests
Opened
#668 Facet-value typeahead misses accented values on the EF-sourced fields (LOWER() is ASCII-only on SQLite)
Opened
#669 Song artist typeahead scans the whole SongMetadata table per keystroke — consider a normalized SongArtist join table
Opened
#670 FillerPresets: collection-family selections outside the first 100 browse rows render as #150 instead of a name
Opened
#671 Rerun collections: the list endpoint returns a null selection for every row, and the detail GET 500s or nulls for five media types
Opened
#672 review-verdict.yml is head-resolved, so a PR editing it can self-approve the required check
Opened
#674 decisions_validate.py stays green on frontmatter PyYAML rejects — an apostrophe in a single-quoted scalar (hit twice in one session)
Opened
#677 Selection-id boundary: ScheduleItemInspector is unguarded, and list-backed pickers drop malformed options silently
Opened
#684 main is red: the #650 pageSize call-site guard keys its registry on line:column, so any merge that shifts a line breaks it
Opened
#685 CollectionsScreen AddItemsDialog windows the whole media-library type on an empty query, with no truncation surfaced (§3b deviation)
Opened
#688 decisions_validate ceiling calibration test is one line from red — any record ≥61 prose lines fails script-tests
Opened
#689 LibraryFolderDedupeMigrationTests claims CI sets ETV_REQUIRE_MYSQL_TESTS=1 — nothing does
Opened
#690 Rerun collections: paged list TotalCount ignores the search query, so the SPA renders empty pages
Opened
#691 SongVideoGenerator dereferences the nullable SongMetadata.Artists unguarded — NRE on the playback path
Opened
#697 ETV_STATUS_AUTH can write commit statuses, so any head-resolved workflow can still forge review-verdict/h10
Opened
#698 The review-verdict/h10 exemption path decides from mutable PR state — three routes to a forged exemption
Opened
#701 Search indexers mutate SongMetadata.Artists on a possibly-tracked entity (??= []) — same shape rejected in #691
Opened
#706 review-verdict/h10 writes are not serialized — a stale run can overwrite a fresher verdict (ABA retarget + human-rejection race)
Opened
#707 pr-changed-files.sh paging can drop a path when the base branch advances mid-enumeration
Opened
#708 Reproduce #698 route 2 live: push code onto a renovate-authored PR branch and confirm the manifest allow-list refuses the exemption
Opened
#711 .codex/ mirrors the gate-enforcing hooks but is absent from the merge gate's PROTECTED list
Opened
#713 chore: ignore .codex/ and stop shipping a plaintext Gitea credential in tracked docs
Opened
#715 chore(deps): land the three stalled Renovate patch bumps as one batch (#679, #680, #681)
Opened
#719 H11 pre-push guard blocks a tag-only push, on every release cut
Opened
#720 docs(ci-cd): a Komodo stack named ersatztv now exists on jazz — and it is NOT prod
Opened
#721 Auto-Tune proposal rows should be a grid — channel numbers do not line up, and the name renders twice
Opened
#726 Embedded BITMAP subtitle (PGS/DVD) burn-in + -readrate halves transcode to 0.53x realtime — Live TV buffering
Opened
#727 FFmpeg version health check warns on our own bundled FFmpeg — hardcoded 7.1.1 vs bundled 8.1.2
Opened
#728 Channels list: row checkbox renders a visible "Select <channel name>" label, duplicating the name column
Opened
#729 Channel edit → Branding: logo renders broken — detail endpoint returns a relative logo path, list endpoint returns absolute
Opened
#730 Settings → System: stale "managed in the legacy UI" copy pointing at a UI removed in #91b, and it renders as a dead link
Opened
#731 Dashboard "On air now": channel logo never rendered — ChannelLogo is called without src, always falling back to initials
Opened
#732 On Now / Next overlay: give it a boxed background for legibility, and enable it on all channels by default
Opened
#733 dvbsub/dvb_subtitle are missing from both IsImage lists, so DVB bitmap subtitles are routed down the text/libass path
Opened
#734 SPA: field-level progressive disclosure — short summary → hover popup → (future) deep-dive docs link
Opened
#735 Validate FFmpeg profile numeric fields to sane ranges instead of silently transforming them, and expose readrate pacing as a bounded field
Opened
#736 Advanced: editable FFmpeg arguments box — show the composed command, allow override, reset to default
Opened
#740 AddItemsDialog.runSearch has no stale-response or is-mounted guard (pre-existing, surfaced during #685)
Opened
#742 Tighten review-verdict.yml provenance from "non-null creator" to an allow-list of approved reviewers
Opened
#743 review-verdict/h10 is bypassable without forging it: direct pushes to main are server-side permitted
Opened
#744 ci-image.yml's push trigger has no branches: filter — any branch push runs attacker YAML on a docker-capable runner
Opened
#746 docker-build.yml checkouts should set persist-credentials: false — after the || true fetch masking is removed
Opened
#747 Re-verify the Gitea 1.25.4-pinned CI claims after the 1.27.1 upgrade
Opened
#748 Declare permissions: on the status-writing workflows so the Gitea Restricted token default can be enabled
Opened
#751 review-verdict.yml's classify/post step never executes — job goes green, review-verdict/h10 is never posted automatically
Opened
#754 MCP ersatztv_update_channel omits graphicsElementIds — cannot set the On Now/Next overlay, and silently strips it
Opened
#755 Project boundary: ersatztv owns the fork code, media-management owns channel operations
Opened
#756 Extend the dropped-step guard to docker-build.yml's required jobs, where a dropped step is fail-OPEN
Opened
#757 MCP tool catalog: query parameters are unguarded — list_playouts omits query, get_playout_items omits showFiller
Opened
#758 GetPagedPlayouts: TotalCount ignores the query filter, so a filtered page reports the unfiltered total
Opened
#759 MCP query-parameter guard ignores a $ref'd OpenAPI parameter instead of failing loudly
Opened
#763 Page both /statuses/{sha} reads in review-verdict.yml — limit clamps to 50, so the post-write race check can miss a raced verdict
Opened
#767 Make the delimiter ban fail-CLOSED on the release path — build's Smoke step is still droppable on a v* tag push
Opened
#772 The pinned CI toolchain image can vanish from the registry and take ALL container CI down, with no signal but a pull error
Opened
#773 Root-cause the recurring defect shapes across closed issues, then build hooks/tooling that make them hard to repeat — plus an audit of the tooling we already have and don't use
Opened
#774 Guard convention: derive the expected set from the authoritative source and assert equality — never filter, never sample
Opened
#775 Every guard ships with a proof it can go red: delete that guard alone, the suite must fail
Opened
#776 Make hooks report that they fired — PreToolUse/PostToolUse execution is currently unobservable
Opened
#777 csharp-lsp and typescript-lsp are broken; the "workflow agents must use csharp-lsp" guidance is stale
Opened
#778 Audit read-then-write against live remote state: pin a version or use compare-and-set
Opened
#779 Test the deny path with the production config value, and assert full-replace field lists
Opened
#780 Reconcile Python tooling: commit a ruff config and enforce it, or stop claiming we enforce it
Opened
#781 Plugin/MCP config hygiene: retire what is enabled and never invoked, de-duplicate the gitea server
Opened
#783 ersatztv skill states the stack names correctly but does not warn that two of the three fail silently
Opened
#784 Generalize the no-session-narrative rule from the kickoff file to all docs — the reader never saw the earlier draft
Opened
#785 Mutation proofs for the 19 unproven guards, worst-consequence first
Opened
#786 Extend the machine-checked guard inventory to inline workflow-job guards
Opened
#787 The dropped-step guard's SCOPE is a dated comment, not a check, against branch protection
Opened
#788 One shared verdict vocabulary instead of two shell copies plus a parity test
Opened
#789 Derive the CI toolchain population from workflow-owned metadata, not TOOLCHAIN_JOBS
Opened
#790 An executable clause-level mutation harness for the shell and python guards
Opened
#792 post-review-verdict.sh exits 0 when it deliberately writes NO status
Opened
#794 A fix ships a test witnessed failing BEFORE the fix — mechanise it by reverting the code side and asserting red
Opened
#796 A verification harness is itself unproven code — five false greens, each created by the fix for the last
Opened
#797 pretooluse-bom-guard.sh is fail-open wherever xxd is not installed — including the CI runner
Opened
#799 serena is enabled and starts fine, but its tools never reach a session — establish why, then use or disable it
Opened
#803 Head-ABA: a force-push H1->H2->H1 during paging defeats pr-changed-files.sh, and three contracts still deny it
Opened
#806 Guard populations over FILES should derive from the git index, not a filesystem walk
Opened
#807 The SPA's hand-built request objects can silently drop an OPTIONAL DTO field
Opened
#809 The production-hook-fire-log isolation guard is per-test, but its claim is per-suite
Opened
#812 Remediate the 21 session-narrative sites #784's sweep found — 21 judgements, not a regex
Opened
#816 Mutation harness: reset_sandbox does not restore .git control state
Opened
#819 The SPA page-size guard enumerates web/src with a Vite glob while claiming completeness
Opened
#820 Complete<T> proves its semantics but not its APPLICATION — nothing derives the set of SPA full-replace construction sites
Opened
#821 curl -u "$VAR" puts a credential in argv on shared hosts — five call sites, one class
Opened
#822 test_the_suite_does_not_write_to_the_PRODUCTION_log uses global mutable state as its oracle — any concurrent session reddens it
Opened
#823 Scheduling collection-valued columns: is a runtime null reachable on DaysOfMonth / MonthsOfYear / DaysOfWeek?
Opened
#824 ElasticSearchIndex.UpdateSong has no regression test — an Elastic-only reintroduction of the #701 mutation stays CI-green
Opened
#830 AddItemsDialog: a failed add is silently swallowed when the dialog is closed mid-request
Opened
#832 MediaCards paged handlers: 1-based paging + delete-or-keep (count drift fixed in #690/#758)
Opened
#835 Guard the persist-credentials convention — after #744, with no exemption list
Opened
#836 :latest images ship InformationalVersion 0.0.0 — a --depth=2 fetch grafts the build job's full clone shallow
Opened
#837 Scripted-playout _off: the documented "null -> all off" behaviour depends on an unrecorded formatter setting, and no test would catch it changing
Opened
#839 FieldHelp's panel placement is verified by hand, not by a test
Opened
#840 FieldHelp's portalled panel puts a docsHref link at the end of the tab order
Opened
#844 Per-channel default-adoption state, so "on by default" can stop re-adding an overlay the operator cleared
Opened
#845 post-review-verdict.sh does not check that its own account is on the gate's H10_REVIEWERS allow-list
Opened
#848 The QSV frame-pool 422 can name a control the editor is not rendering
Opened
#849 review-verdict.yml post-write verification: three routes that leave an exemption success over a human failure
Opened
#853 workflow_dispatch still loads attacker YAML from an arbitrary ref — four workflows, no ref restriction
Opened
#854 docker/ci/Dockerfile's FFMPEG-bump comment still says a push publishes — and cannot be fixed on its own
Opened
#855 Nothing couples ci-image.yml's push.paths to ci-image-pin's expected pathspec
Opened
#858 pretooluse-merge-consent.sh resolves its verdict classifier from $CLAUDE_PROJECT_DIR — an env var as a security input
Opened
#859 Merge-gate branch-protection read: a malformed rule states a cause that did not happen, and the endpoint is now fetched twice
Opened
#869 Finish the 1.25.4-dated CI claim sweep #747 deliberately did not complete
Opened
#870 The timeline walk's null terminator is defeatable: Gitea pages BEFORE it filters, so a page of inline-code comments reads as exhaustion
Opened
#876 docs.no-session-narrative reaches hooks and code comments, but nothing has ever swept them — 4 known sites
Opened
#877 Dismissible write failures, shape A2: the error state survives but its render site is gated by the same condition dismissal clears
Opened
#880 Schedule-item recurrence fields: an omitted array means "never applies" on write but "unrestricted" on read
Opened
#881 Mutation claims in PROSE are outside testing.mutation-claims-are-executed — 4 false ones in #812, each caught by a separate review round
Opened
#885 Same-repo pull_request runs get REGISTRY_PASSWORD from head-supplied YAML — the route #853 found under the dispatch class
Opened
#886 release.verdict-vocabulary-shared explains the sentinel with a set -u mechanism that measurement refutes
Opened
#887 Every image build fails: completeAnnotations.guard.test.ts needs the git index, and the Dockerfile's exclude list is hand-maintained
Opened
#891 ETV_HOOK_FIRE_LIB is SOURCED from an env-var path in 12 hooks — a decoy tree's code runs inside the gate
Opened
#893 page_statuses still terminates on its first empty page — is /statuses/{sha} subject to #870's post-pagination filtering?
Opened
#894 SPA lets a user build an empty recurrence set the server now rejects (#880 residual)
Opened
#895 "all N tests stayed green" claims in test comments go stale the moment anyone adds a test — 4 found, no detector
Opened
#900 chore(release): cut and promote v26.15.0 on 736649b3b (main head could not build an image)
Opened
#901 Convention: for a predicate over shell or config TEXT, pin the artifact whole — "match a shape" is the exception that must argue for itself
Opened
#904 test_docs_only_detector_clone_depth.py flakes ~8% in the CI container (measured, pre-existing on main)