Skip to content

DestKind is declared twice and joined by an unchecked string conversion #712

Description

@rainmanjam

From the poka-yoke audit of 2026-09-04. Lens: fixed-value. Today: rung 0. Device reaches: rung 2 (Warning). Silent, and confinement-adjacent.

The mistake available

Add a fifth destination kind — an HLS or WHIP output — to internal/db and not
to internal/ffmpeg.

Two independent declarations of four values each:
internal/db/destinations.go:18-28 and internal/ffmpeg/build.go:831-842,
joined by ffmpeg.DestKind(row.Kind) at internal/engine/destinations.go:443
and internal/api/expert.go:436. That conversion compiles for any string.

What happens

internal/engine/destinations.go:693:

func destWritesAFile(row *db.Destination) bool {
	switch row.Kind {
	case db.DestFile:  return true
	case db.DestAudio: return !strings.Contains(row.URL, "://")
	default:           return false      // a new file-writing kind lands here
	}
}

The comment above it states the stake: "Without this an audio file target would
be written relative to the process working directory, outside the confinement
every other file destination has."
A new kind silently inherits false.

Separately, build.go:1286 and build.go:1368 switch on s.Kind over
RTMP/SRT/File with no default — a fifth kind emits no -f at all and lets
FFmpeg guess the muxer from the target string. build.go:1364 warns about
exactly this in prose.

Today

Rung 0. db.Destination.Validate has a hand-listed
case DestRTMP, DestSRT, DestFile, DestAudio: that must be remembered too.

Device → rung 2, Warning

exhaustive in golangci-lint with default-signifies-exhaustive: false, plus a
default: arm in destWritesAFile that returns true — fail closed. The
confinement is cheap; the alternative is an arbitrary-file-write primitive.

What stops Control: it would need ffmpeg to import db's type rather than
redeclaring it, and the redeclaration is deliberate — internal/ffmpeg is
dependency-free by design. The linter is the honest ceiling.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions