decisions corpus consolidation has no owner — and after #610 the budget number stops reporting it #620
Closed
opened 2026-07-25 19:36:08 +02:00 by timothy
·
2 comments
No Branch/Tag Specified
main
renovate/lucene.net
renovate/dotnet-monorepo
renovate/sqlitepclraw.bundle_e_sqlite3-3.x
renovate/meziantou.analyzer-3.x
renovate/cliwrap-3.x
913-scripted-playout-401
release/v26.15.0-notes
issue-806-guard-populations
scratch/767b-poisoned
scratch/767b-control
release/v26.14.0-notes
release/v26.14.0
docs/510-skill-logo-bug-policy
fix/510-watermark-resolution-policy
fix/629-verdict-classifier-falseopens
fix/609-decisions-edit-token-scope
issue-135-clear-to-none
release/v26.12.0-notes
fix/409b-lastscan-api-parity
fix/401-updatechannel-mirror-422
fix/327-playlist-rename-validation
fix/410-scancancel-log-level
fix/409-447-librariesscreen-neverscanned
fix/338-zap-exit-code
fix/367-plex-budget-message
fix/310-debom-legacy-cs
ci/604-lane-rebalance
feat/388-design-mirror
feat/247-test-ownership
feat/247-primary-action
feat/357-player-owned-playback
feat/357-jellyfin-plugin-poc
fix/289-mcp-hardening
issue58-mcp
feat/244-channels-extract
ci/auto-bump-prod-compose
feat/multi-rerun-collections-api
feat/collections-api
feat/quick-wins
feat/185-docs-part2
feat/140-collections-screen
feat/146-channel-edit
feat/147-classic-ui-link
issue22-renovate-dashboard
feat/91-cutover
feat/63-composite-create
feat/65-library-browse
feat/85-epg
feat/86-schedule-editor
feat/109-dashboard-data
feat/99-session-tracking
fix/dockerfile-node-tag
feat/59-spa-foundation
docs/59-ui-redesign-brief
feat/102-json-guide
feat/111-schedule-durations
feat/104-artwork-upload
feat/103-media-sources-api
feat/playouts-read-api
feat/108-health-api
feat/105-picker-list-endpoints
issue-97-channel-state-api
issue42-jellyfin-musicvideos
issue46-rest-api-error-contract
dependabot/nuget/ErsatzTV.FFmpeg.Tests/multi-d307a2e06f
qsv-improvements
hdr-vulkan-cuda-test
v26.16.0
v26.15.0
v26.14.0
v26.13.0
v26.12.0
v26.11.0
v26.10.0
v26.9.0
v26.8.0
v26.7.0
blazor-final
v26.6.0
v26.5.0
v26.4.0
v26.3.1
v26.3.0
v26.2.0
v26.1.1
v26.1.0
v25.9.0
v25.8.0
v25.7.1
v25.7.0
v25.6.0
v25.5.0
v25.4.0
v25.3.1
v25.3.0
v25.2.0
v25.1.0
v0.8.8-beta
v0.8.7-beta
v0.8.6-beta
v0.8.5-beta
v0.8.4-beta
v0.8.3-beta
v0.8.2-beta
v0.8.1-beta
v0.8.0-beta
v0.7.9-beta
v0.7.8-beta
v0.7.7-beta
v0.7.6-beta
v0.7.5-beta
v0.7.4-beta
v0.7.3-beta
v0.7.2-beta
v0.7.1-beta
v0.7.0-beta
v0.6.9-beta
v0.6.8-beta
v0.6.7-beta
v0.6.6-beta
v0.6.5-beta
v0.6.4-beta
v0.6.3-beta
v0.6.2-beta
v0.6.1-beta
v0.6.0-beta
v0.5.8-beta
v0.5.7-beta
v0.5.6-beta
v0.5.5-beta
v0.5.4-beta
v0.5.3-beta
v0.5.2-beta
v0.5.1-beta
v0.5.0-beta
v0.4.5-alpha
v0.4.4-alpha
v0.4.3-alpha
v0.4.2-alpha
v0.4.1-alpha
v0.4.0-alpha
v0.3.8-alpha
v0.3.7-alpha
develop
v0.3.6-alpha
v0.3.5-alpha
v0.3.4-alpha
v0.3.3-alpha
v0.3.2-alpha
v0.3.1-alpha
v0.3.0-alpha
v0.2.5-alpha
v0.2.4-alpha
v0.2.3-alpha
v0.2.2-alpha
v0.2.1-alpha
v0.2.0-alpha
v0.1.5-alpha
v0.1.4-alpha
v0.1.3-alpha
v0.1.2-alpha
v0.1.1-alpha
v0.1.0-alpha
v0.0.62-alpha
v0.0.61-alpha
v0.0.60-alpha
v0.0.59-alpha
v0.0.58-alpha
v0.0.57-alpha
v0.0.56-alpha
v0.0.55-alpha
v0.0.54-alpha
v0.0.53-alpha
v0.0.52-alpha
v0.0.51-alpha
v0.0.50-alpha
v0.0.49-prealpha
v0.0.48-prealpha
v0.0.47-prealpha
v0.0.46-prealpha
v0.0.45-prealpha
v0.0.44-prealpha
v0.0.43-prealpha
v0.0.42-prealpha
v0.0.41-prealpha
v0.0.40-prealpha
v0.0.39-prealpha
v0.0.38-prealpha
v0.0.37-prealpha
v0.0.36-prealpha
v0.0.35-prealpha
v0.0.34-prealpha
v0.0.33-prealpha
v0.0.32-prealpha
v0.0.31-prealpha
v0.0.30-prealpha
v0.0.29-prealpha
v0.0.28-prealpha
v0.0.27-prealpha
v0.0.26-prealpha
v0.0.25-prealpha
v0.0.24-prealpha
v0.0.23-prealpha
v0.0.22-prealpha
v0.0.21-prealpha
v0.0.20-prealpha
v0.0.19-prealpha
v0.0.18-prealpha
v0.0.17-prealpha
v0.0.16-prealpha
v0.0.15-prealpha
v0.0.14-prealpha
v0.0.13-prealpha
v0.0.12-prealpha
v0.0.11-prealpha
v0.0.10-prealpha
v0.0.9-prealpha
v0.0.8-prealpha
v0.0.7-prealpha
v0.0.6-prealpha
v0.0.5-prealpha
v0.0.4-prealpha
v0.0.3-prealpha
v0.0.2-prealpha
v0.0.1-prealpha
Labels
Clear labels
ad-hoc
api
bug
ci-cd
content
dependencies
enhancement
frontend
in-progress
jellyfin
parked
priority: high
priority: low
priority: medium
review
security
One-off / ad-hoc work not tracked by a dedicated issue
REST API / HTTP endpoints
Something isn't working
Build, test, deploy pipeline
Channel content / schedules / playlists
Dependency updates (Renovate)
New feature or improvement
ChicoryTV React SPA frontend
Claimed by an active session — do not pick up
Jellyfin tuner / IPTV integration
Excluded from automatic queue pickup; work only when explicitly selected
Adversarial review finding
Security / vulnerability fix
Milestone
No items
No Milestone
Projects
Clear projects
No projects
No Assignees
Notifications
Due Date
No due date set.
Depends on
Reference: timothy/ersatztv#620
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
The concern
Nobody owns consolidating the decision corpus, and the one signal that used to nag about it is being replaced by a healthier-looking number that measures something different.
Two states, before and after #610
On
maintoday (798ecd1f), the validator emits this on every run, local and CI:438 over, and it had been firing continuously rather than as an event — a permanently-red ratchet, which provides no signal at all.
After #610 / PR #619 merges, the budget counts prose only, excluding YAML frontmatter, and the corpus reads 5228/5600 — under budget for the first time. PR #619 states this plainly and is right to: no knowledge was removed. It is a change of metric, not a consolidation.
So the warning goes quiet without the underlying condition changing. That is the actual risk this issue exists to name: a check that stops complaining because it started measuring something else reads, to a future session, exactly like a problem that got fixed.
Why this still matters once the number looks fine
Sequencing
Do not start before #610 / PR #619 merges. It moves every record to
records/<area>/<topic>.mdand changes both the unit of consolidation and the metric. Starting earlier means doing the work twice.Scope when picked up
docs.tracker-comment-retrofit). #610's own inventory found ~500 lines of non-record narrative a naive move would have deleted — that trap applies just as much to consolidation.status: superseded/retired), never a silent line-delete — and now needs aDecisions-Edit: yestrailer (#609).schedvsscheduling, seven single-record areas,lockingoverlappingconcurrency) is related but separate — #610 deliberately preserved keys verbatim because renaming a key changes identity and invalidates MemPalace's per-key drawers. Fold it in only if that's a deliberate decision, with its own record.Non-goals
::warning::by design (#520) and should stay that way — a size condition turning an unrelated PR red is a self-inflicted CI outage.Done-when
decisions corpus is 438 lines over the aggregate budget — the validator warns on every run and nobody owns the consolidationto decisions corpus consolidation has no owner — and after #610 the budget number stops reporting itClaiming — picked up as the top-ranked eligible backlog item by
scripts/select-queue.sh(tierprio-medium, deps clear now that #610/PR #619 has merged, which was the stated sequencing gate).Scanning for bundle-able siblings in the same subsystem (#621 structural parse check, #631
scripts/tests/not run in CI) before scoping.Closing record
Outcome: Shipped in PR #642 (merged). The aggregate corpus budget is retired, replaced by a per-record prose ceiling (
--record-ceiling, default 60), both non-blocking. New decision recorddocs.corpus-size-signal.Root cause / the premise had already expired. This issue was filed because the budget went quiet at 5228/5600 after #610 changed the metric — a check that stops complaining because it started measuring something else. Measured on
mainatf394d6ceit was 5658/5600, over budget and warning again — 3 hours 35 minutes later, the same evening, with nobody consolidating anything. So the answer was not to re-baseline: an aggregate over a monotonically growing corpus can only ratchet, which is the "permanently red, therefore no signal" state #542 re-baselined away from. Growth is not even a smooth rate to plan against — the corpus fell from 5089 to 5042 across four days, then gained 427 in one evening as two large records landed.Decisions/conventions changed: added
docs.corpus-size-signal. Also stopped counting the generated catalog in the total (189 of those 5658 lines): it gains one row per record and no consolidation can shrink it, which quietly made the metric partly a record count wearing a line-count costume, pointing readers at work that cannot be done.Reusable knowledge — the calibration test took four versions, and the failures are the lesson:
max(under) <= 60 < min(over)p90 <= ceiling <= p95Two rules that outlive this metric: a guard test must depend only on the thing it guards, and a threshold over a growing population must be expressed in that population's own terms — a percentile, not a count and not a raw distance.
A third, learned the hard way: do not freeze a self-referential number in prose. This record's own line count was restated and wrong four times (62 → 68 → 88 → 92) as each correction changed it. Every self-count is now absent; the warning prints the live value. The candidate table is likewise labelled point-in-time, since the over-ceiling set moved during the PR's own review cycle.
Verification: mutation-verified throughout — re-adding the catalog to the total, making the ceiling inclusive, neutering
main()'s ceiling report, bumping the default to 999999, and suppressing the trend notice each redden exactly their own test. Four independent cold review rounds; every historical figure in the record was independently reproduced by a reviewer (5658/189 atf394d6ce, 5228 at8e84191a, the 3h35m interval, the 5089→5042→5469 series, 628 scaffolding lines, all candidate line counts). 225 tests green.Deferred: two records remain flagged as genuine consolidation candidates —
scan.projection-failure-sweep-guard(overlapsscan.zero-item-fetch-guard) andsched.weighted-shuffle(overlapssched.weightedshuffle-editor). Merging records changeskeyidentity and invalidates MemPalace's per-key drawers, so that is a call for the owning area, not a drive-by edit inside a metric change. The standing warning names them every run, which tracks them better than an issue nobody reads. An automated redundancy metric was rejected, not deferred: noisy, unfalsifiable, and it would fire hardest on the adjacent-but-distinct records the corpus exists to keep apart. Taxonomy normalisation stays out of scope for the same identity reason.Docs updated:
docs/decisions/records/docs/corpus-size-signal.md(new),docs/decisions/README.md(regenerated),docs/ci-cd.md,docs/decisions.md(the retired budget no longer reads as a live check).