030a7c19e9945aa0af8d3c5e4bcf8bddcb85bf8a
9
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
030a7c19e9 |
chore: widen the BOM-guard remedy to staged + dirty files (review nit)
Build ErsatzTV Image / CI image pin matches docker/ci (pull_request) Successful in 5s
Build ErsatzTV Image / Docs update reminder (pull_request) Successful in 5s
Build ErsatzTV Image / decisions.md append-only (pull_request) Successful in 6s
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 5m18s
Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (pull_request) Successful in 14s
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (pull_request) Successful in 14s
Build ErsatzTV Image / Functional E2E (curl contracts) (pull_request) Successful in 3m9s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 13m30s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
Cold review (MERGEABLE-WITH-NITS) flagged that the printed fix snippet and the docs by-hand check used `git diff origin/main...HEAD`, which excludes staged-but-uncommitted files. A brand-new staged .cs is exactly what fires the pre-commit deny yet is absent from that diff, so the copy-paste remedy would strip nothing → deny again → loop. (The deny still names the file, so manual stripping always worked; this just makes the printed remedy match the guard's own detection set: branch diff ∪ staged ∪ dirty.) Verified on a fresh fixture: a brand-new staged BOM file is denied, and the widened snippet strips it. Left as accepted (fail-open, Medium, CI backstops; shared with sibling hooks): `git -C <path>` isn't parsed for the target tree (only `cd` is — matches the `cd <wt> && git` usage here), and the heredoc-body false-deny vector that bash-guard/worktree-guard also carry. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
9e1fce1a3a |
chore: PreToolUse guard that blocks a commit/push with a BOM'd touched .cs
Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (pull_request) Successful in 16s
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (pull_request) Successful in 16s
Build ErsatzTV Image / Functional E2E (curl contracts) (pull_request) Successful in 9m56s
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 13m58s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 14m16s
Build ErsatzTV Image / CI image pin matches docker/ci (pull_request) Successful in 5s
Build ErsatzTV Image / Docs update reminder (pull_request) Successful in 4s
Build ErsatzTV Image / decisions.md append-only (pull_request) Successful in 4s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
The #311 fix-as-you-touch rule is already enforced by a pre-commit hook and a blocking CI job, and both missed the same mistake twice on 2026-07-17: PR #405 shipped 6 BOM'd files, PR #402 shipped 19. The gap is that the pre-commit hook is routinely skipped — worktree hook friction makes `git commit --no-verify` the normal path here — which leaves CI, a ~10-minute round trip, as the first thing that tells you. This guard fires on Bash before git runs, so --no-verify can't skip it. It denies `git commit`/`git push` when a .cs the branch touches still carries a BOM, names the files, and gives the strip command. Why a hook rather than a note: a memory describing this exact trap did not prevent either failure — the PR #402 session re-added a BOM an hour after writing that memory down, because the usual ways of touching a legacy file re-add it silently (Python io.open(..., encoding='utf-8-sig') WRITES a BOM back; sed/perl round-trips keep it). A check that runs beats one you have to remember. Follows the existing gate pattern: a fail-open script in .claude/hooks/ registered on the PreToolUse/Bash matcher alongside bash-guard and worktree-guard. Any parse or lookup trouble → allow; this must never be the reason a commit can't happen, and CI remains the backstop. Generated *.Designer.cs / TvContextModelSnapshot.cs are exempt, matching what dotnet format itself skips. Scoped to this repo, and it resolves the target tree from an in-command `cd` because commits here run as `cd <worktree> && git ...` and the harness resets the shell cwd between calls. Verified against a throwaway fixture: denies commit and push for a BOM'd touched file (naming it); allows a clean tree, a BOM in generated files only, `git status` with a BOM present, and `echo 'run git push later'` (no false-trip on the words). Proved live via a sentinel — it fires on the Bash matcher — sentinel removed. docs/contributing.md updated: three enforcement layers, why the third exists, the utf-8-sig re-add trap, a by-hand check, and the bash-not-zsh caveat for `dotnet format --include` (mapfile is bash-only; under zsh the file list is empty and the tool looks like it silently did nothing). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
10ae885b47 |
fix(analyzers): preserve non-CPM and image builds
Build ErsatzTV Image / Docs update reminder (pull_request) Successful in 9s
Build ErsatzTV Image / decisions.md append-only (pull_request) Successful in 10s
Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (pull_request) Successful in 17s
Build ErsatzTV Image / Functional E2E (curl contracts) (pull_request) Successful in 5m12s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 5m52s
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (pull_request) Successful in 2m40s
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 8m40s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
Guard analyzer package references for the inline-version MCP tool and copy the SDK suggestion baseline into the Docker build context before restore. Refs #15 Co-Authored-By: Codex <codex@openai.com> |
||
|
|
8f90cea5cc |
feat(analyzers): enable incremental latest-All enforcement
Centralize SDK and threading analyzers, baseline the .NET 10 All rule inventory at suggestion severity, and promote S3981 repo-wide. Fix the always-true worker count predicate and cover the idle/active branches. Fixes #15 Co-Authored-By: Codex <codex@openai.com> |
||
|
|
19dbfe9a8b |
docs(process): #311 — formatting-as-you-touch (§7) + rebase-not-merge lore + decisions entry
- contributing.md §7: document fix-formatting-as-you-touch (normalize a legacy file you edit, incl. BOM strip; no big-bang), enforced by the pre-commit hook + the new format CI job. - kickoff lore: flip "merge main into PR branch" -> "rebase on origin/main" (H11 enforces it); keep the regenerate-generated-artifacts-on-conflict nugget. - decisions.md: new entry (+ TOC) for both decisions. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
408b0deb89 |
feat(91b): remove legacy Blazor Server UI (#91 phase b)
Build ErsatzTV Image / Docs update reminder (pull_request) Successful in 8s
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 6m39s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 6m3s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
The ChicoryTV React SPA (web/, served at /app) now has full parity for every route the Blazor UI served, so the legacy Blazor Server / MudBlazor UI is deleted. This is the milestone-capping removal of #91 phase (b). Deleted: ErsatzTV/Pages/**, Shared/**, ViewModels/** (39 edit VMs), Validators/** (10 edit-VM validators), App.razor, _Imports.razor, Locals/{Shared,Pages}/** (Blazor loc resx; Locals/Resources.* kept), wwwroot/css + wwwroot/lib, libman.json, and the orphaned MultiSelectBaseTests. Startup.cs (surgical, not wholesale): removed AddRazorPages/AuthorizeFolder, AddServerSideBlazor, AddMudServices, AddSortable, AddCourier, the HtmlSanitizer registration, the Blazor-attached OIDC UseAuthentication/UseAuthorization middleware (per the #206 auth-posture sign-off), MapBlazorHub, and MapFallbackToPage("/_Host"). Renamed the branch blazor->legacy; it still co-hosts MapControllers, /docs (Scalar), dev MapOpenApi and the redirect middleware. Replaced the _Host fallback with a catch-all (MapFallback -> 302 /app) that excludes /api|/artwork|/docs|/openapi (genuine 404) per #204. Kept all OIDC/JWT/API-key service wiring (inert unless configured; real auth is #197), ConditionalIptvAuthorizeFilter, ApiKeyAuthorizationFilter. Pruned 9 now-unused packages (all verified zero remaining consumers) from Directory.Packages.props + ErsatzTV.csproj: MudBlazor, Heron.MudCalendar, Blazored.FluentValidation, BlazorSortable, MediatR.Courier.DependencyInjection, Markdig, HtmlSanitizer, Chronic.Core, NaturalSort.Extension. Also removed the now-dead #25 razor-Sonar NoWarn. LegacyUiRedirects: added the 14 /media/sources/* -> /app/libraries/* redirects (SPA screens landed in #202) and lifted the #204-era /media/sources prefix ban. Tests: Release build clean; full solution suite green. Updated Startup source-text tests + added regression coverage that Blazor wiring is gone, the catch-all is wired, and all 14 media-sources routes redirect. Docs: blazor-route-parity.md (phase b COMPLETE), decisions.md (removal entry), CLAUDE.md, contributing.md, README.md all updated in this PR. Rollback: tag blazor-final is cut on pre-merge main as the first merge action. Part of #91. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
0290594f0b |
docs: testing map + generated endpoint index (#185)
Adds docs/testing.md as the authoritative testing map (consolidated from docs/contributing.md §8, now shrunk to a pointer), and a generated docs/endpoint-index.md via scripts/generate-endpoint-index.py (hooked into scripts/update-openapi.sh). Updates docs/README.md's reading order and removes the "still to come" placeholder. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
fe4cd39070 |
fix: make filler scheduling tests timezone-independent (fixes #24)
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 4m53s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 6m12s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
Build ErsatzTV Image / Build & test (.NET) (push) Successful in 5m7s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (push) Successful in 6m34s
Build ErsatzTV Image / Build & push image (amd64) (push) Successful in 5m4s
Should_Not_Crash_Mid_Roll_{Zero,One}_Chapters passed 'new PlayoutItem()'
to AddFiller, whose Start defaults to DateTime.MinValue. The mid-roll Pad
path (PlayoutModeSchedulerBase.cs:609) subtracts 'currentMinute' minutes
from StartOffset; since StartOffset does ToLocalTime(), a non-zero local
offset makes currentMinute non-zero, underflowing DateTimeOffset.MinValue
and throwing ArgumentOutOfRangeException. Under UTC the offset is 0 so it
stays in range (hence CI was green). Unreachable in production — real
playout items never start at MinValue — so this is a test-data artifact,
not a product bug.
Fix: seed the fixtures with a real Start (startState.CurrentTime.UtcDateTime),
matching the convention in the passing AddFiller tests. Verified across
UTC, Europe/Brussels, and Asia/Kolkata (+5:30); full Core.Tests now passes
under any timezone (484/0). Updated docs/contributing.md §8 per its §10
deviation policy.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|
|
969a23909a |
docs: add retroactive contributors/style guide (#10)
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 4m25s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 5m43s
Build ErsatzTV Image / Build & test (.NET) (push) Successful in 3m44s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (push) Successful in 4m53s
Build ErsatzTV Image / Build & push image (amd64) (push) Successful in 3m32s
docs/contributing.md — a descriptive guide to the established patterns, derived from the existing code: architecture/layering, CQRS handler conventions, LanguageExt functional style, Blazor/MudBlazor UI, EF Core + dual-provider migrations, the FFmpeg pipeline pattern, naming/formatting/analyzers, testing, and build/CI — each with concrete file references — plus the deviation policy (match the established style; diverge only with a concrete, stated reason). Several sections are now CI-enforced (#12 layering, #15 analyzers, #13 migrations, #11 golden tests). CLAUDE.md points to it so it's loaded as project guidance. Survey across the sections done with parallel read-only agents; all file references verified to exist. Refs #10 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |