Skip to content

Releases: Pummelchen/Converter

Converter 1.1

Choose a tag to compare

@Pummelchen Pummelchen released this 16 Sep 01:08
d567ba5

Converter v1.1 — release notes

Released 2026-09-16. Previous release: v1.0.

This release changes no conversion behaviour. The executable is byte-for-byte the same build as
v1.0; v1.1 carries the release and identity tooling that RELEASE.md requires, plus
documentation corrections. If you only want the converter, v1.0's artifact and this one are
identical — verify with the checksum block at the end.

Added — a single source for the version

  • VERSION at the repository root is now the one authoritative value, and
    scripts/check-version-sync.sh fails when a mirror disagrees: the topmost ## [X.Y] heading of
    CHANGELOG.md, and the name of this file. Backed by: the gate runs in CI's static-analysis
    job and is exercised by scripts/release.sh, which refuses to build when it fails.
  • The gate was confirmed able to fail before it was trusted — pointing VERSION at a version with
    no matching changelog heading and no notes file makes it exit 1, and CI reports
    ::error::CHANGELOG.md's current heading is ….

Added — a release script

  • scripts/release.sh builds the release, asserts the artifact is arm64 and only arm64
    (lipo -archs), reports the digest and size, and publishes only on an explicit --publish
    (§1.2.6). It refuses when the tree is dirty, when gh is not the repository owner, when the
    rebuilt binary is not the committed one, when the release already exists, when an existing tag
    points somewhere other than HEAD, and when the notes carry neither the placeholder nor the real
    digest and size. Backed by: the script's own preconditions, and a dry run before any tag.
  • The build runs in a fresh scratch path, so the warning scan cannot pass vacuously over an
    incremental build (§1.5).

Changed — documentation

  • docs/RELEASE_CHECKLIST.md is now version-agnostic (it was titled for one release), so it does
    not become a second place to bump.
  • Root-level test counts, the lint budget and the release/build-path facts corrected in README.md,
    CONTRIBUTING.md, AGENTS.md, SECURITY.md and CHANGELOG.md. Backed by:
    scripts/lint-budget.sh and the suites recorded in docs/KNOWN_GOOD_VERSIONS.md.
  • AGENTS.md and RELEASE.md now carry the account-wide release and build rules.

Note — the build is not bit-reproducible

Two builds of the same source produce the same size and the same code, but not the same bytes: the
linker's LC_UUID is regenerated on every link, and the ad-hoc signature covers it. Measured against
the committed binary, a clean canonical rebuild differed in 85 bytes of 1 715 256, with identical
section sizes. A --scratch-path build differs far more — in size and in 17 664 bytes — because the
module metadata follows the build directory, which is why scripts/release.sh builds in the
canonical location and publishes the committed binary.

The consequence is worth stating plainly: the checksum pins the file, not the sources. The
published artifact is the same bytes as v1.0's; a rebuild of the same sources will not reproduce
that hash. Verified with cmp -l, otool -l LC_UUID and codesign -dvvv on both files.

Checks that did not run

  • CodeQL's Swift analysis is still switched off (#0160). GitHub's default-setup runner
    autobuilds with Swift 6.3.3, which cannot parse this package's Swift 6.4 manifest, so the Swift
    language is disabled rather than left silently analysing nothing. Re-check by 2026-10-15. A green
    CodeQL check on this repository therefore does not mean Swift was scanned; the repository's own
    gitleaks, semgrep, cppcheck and clang-tidy gates carry that.
  • The manual smoke test on real media was not run. It needs non-private source material and an
    operator; docs/RELEASE_CHECKLIST.md keeps it as an owner step.
  • The clean-machine auto-install path was not run (CONVERTER_AUTO_INSTALL_DEPS=1), for the same
    reason.
  • The GitHub Actions jobs on the release commit had not run. Every job that needs the
    xcode-27 image was still queued when this release was cut — jobs on that image have been
    waiting for hours, which is a runner-capacity problem on GitHub's side, not a failure. Not
    checked, therefore
    , and no CI result is claimed. Every check those jobs perform was run
    locally on the release commit instead and is reported above: the formatter, the lint budget, the
    Python checks, the version gate, the checksum, gitleaks over all 343 commits, semgrep,
    cppcheck, clang-tidy, the -warnings-as-errors debug build, the strict release build, the
    serial suite (278 tests) and the lipo -archs assertion. The only jobs that did run were the
    ubuntu-latest CodeQL analyses, which passed.

Checksums

  • File: converter
  • SHA-256: 6aba6b23aaa329157b57fb8ae3781c44949fb02f91db243cb76c023f0cbd9ad5
  • Bytes: 1715256
shasum -a 256 -c converter.sha256

Converter v1.0

Choose a tag to compare

@Pummelchen Pummelchen released this 15 Sep 21:03

Converter v1.0 — first stable release.

Swift CLI that turns one song and one image into a complete, verified upload set for macOS Apple Silicon. Every output is verified before it is published: wrong size, wrong codec, silent audio, or drifted loudness fails the run rather than producing a bad file.

Assets

file what it is
converter prebuilt Apple Silicon release binary, 1715256 bytes, SHA-256 6aba6b23aaa329157b57fb8ae3781c44949fb02f91db243cb76c023f0cbd9ad5
converter.sha256 checksum, for shasum -a 256 -c converter.sha256

Built from this tag's commit with swift build --package-path Sources -c release -Xswiftc -warnings-as-errors -Xcc -Wall -Xcc -Wextra -Xcc -Werror on Swift 6.4 / Xcode 27; size, toolchain and source commit are recorded in docs/BINARY_PROVENANCE.md.


What's in this release

First stable release. It is the state of the project after two pre-production audits — 161 tasks
(#1–#0161, 160 DONE, 1 open watch item) — whose whole point was that a conversion should fail
loudly rather than publish something wrong.

Toolchain

  • Swift 6.4 / Xcode 27, Swift language mode 6, swift-tools-version: 6.4, built with
    -warnings-as-errors; the C++ BW64 bridge also builds under -Wall -Wextra -Werror.
  • The Swift layout is owned by swift format (.swift-format, enforced by scripts/check-format.sh
    and a blocking CI step); swiftlint keeps the rule gate with a recorded ratchet that fell from
    461 to 151 violations during the audit. The audit tooling under AUDIT/tools is ruff-clean and
    mypy --strict.
  • CI runs on the xcode-27 image: checksum, lint budget, formatter, Python checks, gitleaks over the
    full history, semgrep, cppcheck (exhaustive), clang-tidy, both builds and the suite.

Fixed

  • A source file can no longer be overwritten by its own render. -aipix/-runpix on a master
    already named <prefix>_8K.png resolved that file as its output, re-rendered it and deleted the
    backup, destroying the original. Every image publish site now refuses output == source, as the
    audio converters already did.
  • The delivered files are verified against the QC ceilings the operator configures. The M4A, the
    MP3 and the main 8K MP4 were published with no absolute audio QC beyond loudness drift and
    audibility; they now take the delivery policy rebased to the source, so an encode is rejected for
    what it added — clipping, DC offset, channel imbalance, true peak.
  • A hung child can no longer stall a finished command. The success path drained stdout/stderr
    without a deadline, so a grandchild holding the pipe hung the run after the child had exited.
  • Cancelling one operation stops only its own work. A cancelled fan-out branch used to SIGTERM
    every live child of the shared runner, failing unrelated branches with a misleading
    "killed by signal 15".
  • Audio actions measure the audio stream, not the container. An MP4/MOV whose video outlasted its
    audio was rejected with a misleading duration mismatch.
  • Verification gaps that could pass by default: canonical-PCM equivalence on two empty decodes,
    padding probes too small to measure, a no-op fade, FLAC bit depth following the source instead of
    the archival standard, and reuse that never checked whether the source had changed.
  • A standard-conforming MP3 with ID3 artwork is copied byte for byte instead of being re-encoded
    into a second lossy generation.
  • File-safety hardening: run-scoped temps created with O_EXCL|O_NOFOLLOW, destination
    permissions preserved on publish, backup recovery that restores rather than deletes after a
    partial replace.
  • Input validation: filter-graph config values must be bare tokens, an explicitly named config
    file that does not exist is an error, out-of-range --sleep-seconds and --num-dots are rejected,
    action-scoped options are rejected by actions that cannot consume them.
  • The entry point is testable and no longer resolves itself against the caller's directory, so a
    converter found on PATH does not read config.txt or write Output in whatever directory you
    happened to be in.

Security

  • gitleaks over the full history reports nothing; the one historical hit is a documented false
    positive (a config-key name beside a parameter label) with a narrow, commented exception in
    .gitleaks.toml that never excludes a file or a commit. Trufflehog, semgrep and cppcheck report
    nothing; clang-tidy reports nothing in first-party code.
  • The auto-install path downloads the Homebrew installer from a pinned commit and refuses to execute
    it unless the SHA-256 matches.

Verified

  • 278 tests, 0 failures, 0 skipped, 0 compiler warnings; coverage 86.99 % of lines / 81.06 % of
    regions / 84.67 % of functions.
  • Phase E ran from a fresh clone on a machine that did not develop the fixes: clean debug and strict
    release builds, committed-binary checksum, every scanner, the full suite, and a -help/-matrix/
    -doctor smoke test.
  • The bundled converter binary is rebuilt from this release's commit; size, toolchain, source
    commit and SHA-256 are recorded in docs/BINARY_PROVENANCE.md and
    checked by CI.

Known

  • Re-enabling CodeQL's Swift analysis is tracked as an open watch item (#0160): GitHub's CodeQL
    default setup autobuilds with Swift 6.3.3, which cannot parse a 6.4 manifest, so Swift is switched
    off there until that image moves. CodeQL still covers actions, C/C++ and Python, and the
    repository's own scanners cover Swift.