Skip to content

docs(web): two false claims about a competitor, and a precondition the copy did not know about - #364

Merged
rainmanjam merged 2 commits into
mainfrom
fix/comparison-claims
Aug 15, 2026
Merged

docs(web): two false claims about a competitor, and a precondition the copy did not know about#364
rainmanjam merged 2 commits into
mainfrom
fix/comparison-claims

Conversation

@rainmanjam

Copy link
Copy Markdown
Owner

Found by the pre-tag sweep, plus a third that only became true this afternoon.

Two cells asserted things about Restreamer their own source refutes

Row Said Actually
Metrics / API them: REST README advertises "optionally by Prom-Metrics"; Core documents Prometheus; they serve GraphQL too
Per-destination loudness them: No FilterSelect per publication, Loudnorm.js among the filters — they do apply one

Both now state what polyemesis does and say nothing about what they do. A blank cell asserts nothing; a wrong one is a claim about somebody else's product on a public page.

The narrowed loudness row is also a better claim: "a target you set — I, LRA and TP" is checkable, where "loudness target" was vague enough to be wrong. Their control is an on/off checkbox emitting the bare string loudnorm, so it takes FFmpeg's defaults and an operator cannot ask for −16 LUFS instead of −24. That is the real difference.

A precondition that did not exist when the copy was written

Wiring Enhanced Broadcasting introduced a second requirement nothing says out loud:

GPUs []MultitrackGPU `json:"gpus,omitempty"`   // empty by default
if len(s.GPUs) == 0 { return nil }             // multitrackGPUs
if len(a.Hardware.GPU) == 0 { return Refused } // Negotiate

Owning a supported GPU is not sufficient. An operator with an RTX 4090 who never fills in the settings block gets the quiet fallback and no explanation. The copy said "it needs a GPU"; it now says it needs a GPU and needs you to declare it — and why: Twitch validates the inventory and refuses a fabricated one by name, so polyemesis does not guess at hardware it cannot measure.

The comparison table's bare "Yes" also became wrong the moment the feature started working. On the headless VPS this audience runs, ticking the toggle now does something real and falls back. COPY-CONSTRAINTS.md:50 requires stating that in the same block as the feature, not a footnote.

Verification

The row-parity guard between the site and docs/COMPARISON.md was mutation-tested, not trusted:

build checks FAILED:
  - comparison.html: capability row "per-destination loudness target you set - i,
    lra and tp, measured after routing" does not appear in docs/COMPARISON.md.

Reverting the document's label while leaving the site's new one fails the build with the drifted row named. Restored; build passes, 6 pages.

Checked and clean

Every other competitor cell was verified true against primary sources by the sweep. All three pages that mention Enhanced Broadcasting now pair it with its GPU requirement. features.astro:29 says it "negotiates" — false yesterday, true now that #363 wires it.

https://claude.ai/code/session_01HeLrWaDmsNeeNSbHQfEofX

…e copy did not know about

## Two cells asserted things about Restreamer that their own source refutes

"Metrics / API" gave them REST and us "Prometheus + REST". Their README
advertises resource monitoring "optionally by Prom-Metrics", datarhei Core
documents Prometheus support, and they serve GraphQL too -- so the cell
understated them twice and implied Prometheus was ours alone.

"Per-destination loudness target" gave them a flat No. They mount a filter
select per publication service and loudnorm is one of the filters offered, so
they DO apply a per-destination loudness filter. What they do not offer is a
target you set: the control is an on/off checkbox emitting the bare string
`loudnorm`, so it takes FFmpeg's defaults and an operator cannot ask for -16
LUFS instead of -24.

Both rows now state what polyemesis does and say nothing about what they do.
A blank cell asserts nothing; a wrong one is a claim about somebody else's
product on a public page. The narrowed loudness row is also a better claim --
"a target you set, I, LRA and TP" is checkable, where "loudness target" was
vague enough to be wrong.

## And a precondition that did not exist when the copy was written

Wiring Enhanced Broadcasting introduced a second requirement nothing said out
loud: `settings.multitrack.gpus` is EMPTY BY DEFAULT, `multitrackGPUs` returns
nil when it is empty, and `Negotiate` short-circuits to Refused on
`len(a.Hardware.GPU) == 0`. So owning a supported GPU is not sufficient -- an
operator with an RTX 4090 who never fills in the settings block gets the quiet
fallback and no explanation.

The copy said "it needs a GPU". It now says it needs a GPU and needs you to
declare it, and why: Twitch validates the inventory and refuses a fabricated one
by name, so polyemesis does not guess at hardware it cannot measure.

The comparison table's bare "Yes" for the second audio mix also became wrong the
moment the feature started working -- on the headless VPS this audience runs,
ticking the toggle now does something real and falls back. COPY-CONSTRAINTS.md
requires that in the same block as the feature, not a footnote.

Verified: the row-parity guard between the site and docs/COMPARISON.md was
mutation-tested -- reverting the document's row label while leaving the site's
new one fails the build with the drifted row named. Restored; build passes.

Claude-Session: https://claude.ai/code/session_01HeLrWaDmsNeeNSbHQfEofX
Copilot AI lite review requested due to automatic review settings August 15, 2026 00:27

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates public-facing copy and documentation to remove incorrect competitor claims and to accurately describe Twitch Enhanced Broadcasting’s operational preconditions, while also wiring the Enhanced Broadcasting negotiation into the engine/UI and tightening several safety/verification guards (encoders, redaction, release, and upgrade scripts).

Changes:

  • Correct marketing/docs comparison claims and add explicit “needs GPU + declared inventory + fallback behavior” messaging for Enhanced Broadcasting.
  • Wire Twitch Enhanced Broadcasting negotiation and status surfacing end-to-end (engine go-live path, settings, destination UI notes, tests).
  • Harden operational correctness: encoder profile coverage (incl. HEVC), upgrade backup verification, log redaction coverage, and release workflow ordering.

Reviewed changes

Copilot reviewed 38 out of 38 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
web/src/pages/index.astro Clarifies Enhanced Broadcasting GPU requirement + fallback behavior on the homepage.
web/src/pages/features.astro Expands Enhanced Broadcasting section to include the “declared GPU inventory” precondition and fallback semantics.
web/src/pages/comparison.astro Removes/refines competitor claims by blanking disputed cells and tightening row wording.
ui/src/pages/SettingsPage.tsx Adds a Settings → Pipeline panel for declaring Enhanced Broadcasting GPU inventory.
ui/src/lib/types.ts Extends UI types for multitrack negotiation notes/verdicts/divergences and settings schema.
ui/src/components/DestinationDialog.tsx Adds UI copy explaining “no GPU declared → negotiation skipped” and where to see the verdict.
ui/src/components/DestinationCard.tsx Renders per-run Enhanced Broadcasting note/divergences and VOD-audio-drop note as non-warning info.
scripts/install.sh Reworks backup verification to avoid SIGPIPE/pipefail false failures by listing once.
scripts/acceptance-encoders.sh Adds an HEVC acceptance leg to catch encoder-flag issues that H.264 legs can’t detect.
scripts/acceptance_encoders_driver.go Implements the HEVC driver mode to exercise a real libx265 rendition.
internal/supervisor/supervisor.go Scrubs give-up-path error logging to prevent stream-key leakage.
internal/supervisor/redact_test.go Adds coverage ensuring “giving up on process” logs don’t leak stream keys.
internal/ffmpeg/synth.go Ensures rate-control mode args are included when generating slate encodes.
internal/ffmpeg/rendition.go Adds HEVC encoder constants/profiles and NVENC CBR/VBR mode selection logic.
internal/ffmpeg/rendition_encoder_profiles_test.go Adds tests asserting HEVC profiles and validating configured encoders against real FFmpeg option behavior.
internal/engine/status.go Surfaces multitrack negotiation notes/verdict/divergences and VOD-audio-drop status.
internal/engine/reload.go Marks multitrack hardware fields as on-demand (applies next go-live), not live-respawn.
internal/engine/multitrack.go Adds the engine-side seam wiring Enhanced Broadcasting negotiation into go-live decisions.
internal/engine/multitrack_wiring_test.go Adds comprehensive engine-level wiring tests for negotiation, fallback, and audio-track gating.
internal/engine/engine.go Adds engine field to inject a multitrack client (for tests) and stores per-destination multitrack decision.
internal/engine/destinations.go Integrates negotiation into startDest, gates second audio track for Twitch, and ensures backups remain one-track.
internal/engine/dest_upstream_test.go Updates test to new startDest signature.
internal/engine/dest_stop_outcome_test.go Adds fake-child behavior to emit last path segment for minted-key scrubbing tests.
internal/engine/dest_shutdown_test.go Updates tests to new startDest signature.
internal/db/settings.go Introduces validated MultitrackSettings (declared GPU inventory) into persisted Settings.
internal/db/rendition_encoder_coverage_test.go Adds meta-test ensuring every UI-offered encoder is configured and produces a viable argv shape.
internal/db/destinations.go Updates VODProfile comment to match new engine enforcement/reporting behavior.
internal/api/redact_drift_test.go Marks multitrack settings fields as public (hardware facts), not sensitive secrets.
internal/alerts/redact_callers_test.go Avoids scanning .claude/ worktrees and allowlists a new Redact caller test path.
docs/UPGRADING.md Documents secret.key backup requirement, update.sh guardrails, and 0.7.0 one-way rollback implications.
docs/RENDITIONS.md Fixes encoder-probing description and documents inferred HEVC verdict behavior.
docs/PLATFORMS.md Corrects Kick OAuth scope list and explains why moderation:ban is now requested.
docs/notes/pre-tag-sweep-v0.7.0.md Adds pre-tag sweep notes capturing verified findings and resolutions.
docs/HARDWARE.md Corrects default encoder behavior and clarifies probe scope and inferred HEVC status.
docs/ENCODING.md Corrects encoder counts/probing claims, NVENC capped-VBR behavior, and profile rules for HEVC vs H.264.
docs/COMPARISON.md Updates row labels/footnotes to remove incorrect competitor claims and reflect new wording.
CHANGELOG.md Adds/updates 0.7.0 entries for Enhanced Broadcasting wiring, encoder fixes, upgrade guard, and documentation corrections.
.github/workflows/release.yml Serializes image publishing behind binaries to avoid half-published releases.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread scripts/install.sh
Comment on lines +1098 to +1102
if ! grep -q "secret\.key" <<<"\$listing"; then
echo "ERROR: the backup contains no secret.key. Restoring without it leaves" >&2
echo "every destination disabled. Refusing to upgrade." >&2
exit 1
fi
Comment on lines +1373 to +1375
each refused by name. polyemesis does not fill this in for you — it can read the PCI vendor
ID of a render node on Linux and nothing else, and sending that one field with zeros in the
rest would be describing a machine that does not exist. Leaving it empty is fine and is the
Comment on lines +1364 to +1367
<CardDescription>
What this machine's GPU is, for the negotiation a destination with Enhanced Broadcasting
switched on makes at go-live.
</CardDescription>
@sonarqubecloud

Copy link
Copy Markdown

@rainmanjam
rainmanjam merged commit 19314db into main Aug 15, 2026
29 checks passed
@rainmanjam
rainmanjam deleted the fix/comparison-claims branch August 15, 2026 00:56
rainmanjam added a commit that referenced this pull request Aug 15, 2026
#364 landed on main touching the same three files this branch's label sweep
touched, so the PR went CONFLICTING. Resolved toward main in every case, because
#364 is more specific and was written against the same sources:

- features.astro, the EB paragraph. main's "it needs a GPU, and it needs you to
  say so" is the better sentence -- it names the precondition that actually bites
  (settings.multitrack.gpus is empty by default, so owning the card is not
  sufficient). Kept, with one clause added: Twitch validates the inventory it is
  SENT rather than the card doing the encoding, which is the mechanism behind the
  refusal main describes. The EXPERIMENTAL note added here sits beside it
  untouched.
- comparison.astro, the Metrics / API row. Pure adjacency -- my hardware-encoding
  comment landed immediately above a row main rewrote. Main's row kept, comment
  moved to sit against the row it is about.
- COMPARISON.md, footnote 4. Both sides claimed the number. Main's loudness and
  metrics correction keeps 4; the hardware-encoding footnote becomes 5, and the
  table cell with it.

web build passes, including check-build.mjs's row-parity guard between the site
and docs/COMPARISON.md -- which is the check most likely to be broken by a
resolution that took one side of these files and not the other.

Claude-Session: https://claude.ai/code/session_01HeLrWaDmsNeeNSbHQfEofX
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants