Without timeouts, a slow/dead-TCP upstream (e.g. github tarballs)
hangs the runner indefinitely. Today run 15185 mpv-fourier-debian
sat 6+ min on "curl -sSLfo mpv.tar.gz https://github.com/.../mpv-0.41.0.tar.gz"
with no progress visible — fermis act_runner blocked, slot unusable
for parallel work.
--connect-timeout 10 fails fast if upstream is unreachable
--max-time 600 caps worst-case at 10 min per fetch
--retry 3 handles transient flakes
--retry-delay 5 gives transient outages a moment
Patched in: claude-his-agent, daedalus-v4l2, daedalus-v4l2-dkms,
libva-v4l2-request-fourier, lmcp, mpv-fourier. ffmpeg-v4l2-request-fourier
has no curl call.
Two follow-ups to PR #44 (which landed the libva-dev ABI pin):
- `051da5e` switch runs-on from arch-aarch64 → debian-aarch64-bohr
- `5feab57` fix runner label: actrunner-debian-aarch64-bohr (label name mismatch in 051da5e)
**Squash on merge** to keep main history clean.
Co-authored-by: Markus Fritsche <mfritsche@reauktion.de>
Reviewed-on: #45
Co-authored-by: Claude (noether) <claude@reauktion.de>
Co-committed-by: Claude (noether) <claude@reauktion.de>
Per @marfrit on PR #44 review: a native Debian trixie aarch64 runner
(debian-aarch64-bohr) is available — use it instead of the sysroot
hack from the previous commit.
The sysroot approach worked but was a workaround for not having the
right runner. Native trixie runner is much cleaner:
- libva-dev installs via apt-get directly from trixie's archive
(2.22.0-3) — pkg-config returns trixie headers, driver compiles
in __vaDriverInit_1_22 naturally.
- No need to symlink libva.so.2 -> libva.so or rewrite .pc prefixes.
- No bsdtar/ar/dpkg-deb juggling on an Arch runner that doesn't
natively have dpkg.
Changes from PR v1:
- .gitea/workflows/build.yml: libva-v4l2-request-fourier-debian
runs-on: debian-aarch64-bohr (was arch-aarch64). Build-deps
installed via apt-get instead of pacman -Syu.
- build-deb.sh: drop the sysroot download / pkgconfig rewrite /
symlink block. Keep the post-build ABI sanity check (nm -D |
grep __vaDriverInit_1_22) — same defensive role as before, with
an updated error message that points to the expected runner.
- debian/.../changelog: -2 entry rewritten to describe the runner
move instead of the sysroot.
Tested approach on boltzmann (aarch64): meson build against trixie
sysroot produces __vaDriverInit_1_22 (proves the source compiles
correctly with VA-API 1.22 headers). Native runner build will
follow the same path, just without the explicit sysroot setup.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The libva-v4l2-request-fourier .deb shipped with the wrong VA-API
symbol export because the CI runner is Arch (libva 2.23 = VA-API
1.23) while the install target is Debian trixie (libva 2.22 = VA-API
1.22). At compile time, <va/va.h>'s VA_MAJOR/VA_MINOR macros are
baked into the driver's __vaDriverInit_<MAJOR>_<MINOR> symbol name.
trixie's libva runtime looks up __vaDriverInit_1_22, our driver only
exported __vaDriverInit_1_23, so dlsym() returned NULL and libva
fell back to its sentinel error "has no function __vaDriverInit_1_0".
Result: ffmpeg -hwaccel vaapi fails on startup, vainfo fails the
same way, on every Pi 5 / CM5 that installed the package.
The driver itself doesn't link libva.so (no NEEDED entry — confirmed
via readelf on higgs), so the only thing that matters is the symbol
NAME the compiler bakes in. Fix is small: in build-deb.sh, download
trixie's libva-dev / libva2 / libva-drm2 .deb from deb.debian.org,
extract to a sysroot, rewrite the .pc prefixes, and set
PKG_CONFIG_PATH so pkg-config returns trixie headers regardless of
what the runner has installed. The link step still resolves -lva
against the sysroot's libva.so.2, but the resulting .so has no
NEEDED entry for it.
Added a hard sanity check at the end of build-deb.sh: fail the build
if the produced .so doesn't export __vaDriverInit_1_22. This makes
future ABI-skew failures loud at CI time instead of silent install-
then-refuse-to-load on the target.
Tested on boltzmann (aarch64): sysroot build produces a .so exporting
__vaDriverInit_1_22 (verified via nm -D). Source unchanged from
c332d34; only the build env differs.
pkgver/upstream unchanged. PKGREL bumped 1 -> 2 (rebuild against
pinned trixie libva-dev) so apt picks up the new .deb on higgs.
This is the LIBVA-2 unblocker — the runtime-libva-bind failure was
masking whether the LIBVA-1 per-codec dispatch actually works on
higgs. Once -2 lands on packages.reauktion.de, apt upgrade on higgs
and the daedalus daemon log + rpi-hevc-dec dispatch can be validated
end-to-end.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Bumps both Arch (PKGBUILD) and Debian (build-deb.sh + changelog)
pins to upstream c332d34 — the merged LIBVA-1 PR.
Effect: Pi 5 / CM5 mixed deployment (higgs) now opens BOTH
rpi-hevc-dec and daedalus_v4l2 from one libva session and routes
per-codec — HEVC to rpi-hevc-dec ('p'), VP9 / AV1 / H.264 to the
daedalus daemon (new 'd' kind). Before c332d34, find_codec_device
picked rpi-hevc-dec by known_decoder_drivers[] order and the
daedalus slot stayed -1, so VP9/AV1/H.264 frames failed S_FMT.
Also closes a small fd leak in RequestTerminate (daedalus pair —
caught while reviewing the alt-driver expansion).
Both packages: pkgver bumped 1.0.0.r378.c332d34, pkgrel reset to 1
(new upstream pin). Backward-compatible on RK3399/3588 — new
branches gated by HAVE_DAEDALUS_V4L2 *and* video_fd_daedalus >= 0,
both false in those deployments.
Companion: daedalus-v4l2{,-dkms} bump 481279c landed in PR #39
(systemd unit + auto-enable). Together they close the Pi 5 stack:
boot → modules-load.d loads daedalus_v4l2 → daedalus-v4l2.service
starts daemon → libva opens both decoders → ffmpeg -hwaccel vaapi
routes by codec.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
481279c adds packaging/systemd/{daedalus-v4l2.service,modules-load} to
the upstream tree. This commit wires those into both the Arch
(PKGBUILD + .install) and Debian (build-deb.sh + postinst/prerm/postrm)
package layouts so that a fresh install of daedalus-v4l2 + daedalus-
v4l2-dkms on a Pi 5 leaves the kernel module loaded at next boot AND
the userspace broker daemon enabled — no manual modprobe / systemctl
enable dance needed.
arch/daedalus-v4l2:
* pkgver 0.1.0.r18.481279c, pkgrel reset to 1 (new upstream pin).
* Dropped 'systemd-libs' from depends — daemon doesn't link
libsystemd (no sd_notify); the .service unit is consumed by
systemd-the-init, no link-time dep required.
* package() now installs the .service to
/usr/lib/systemd/system/daedalus-v4l2.service and the modules-
load drop-in to /usr/lib/modules-load.d/daedalus-v4l2.conf.
* New .install file: post_install/post_upgrade run daemon-reload +
enable + systemd-modules-load + try-restart on upgrade; pre/post
remove tear down cleanly. No auto-start — operator decides.
arch/daedalus-v4l2-dkms:
* pkgver bump to 481279c, pkgrel reset to 1. Kernel module itself
is bit-identical to f0cd29a (commit only touches packaging/) but
bumping in lockstep keeps DKMS source-tree pkgver matched to the
userspace pkgver so /etc/modules-load.d points at a module that
actually exists.
debian/daedalus-v4l2:
* Same bump 481279c, PKGREL=1.
* build-deb.sh stages /lib/systemd/system/ + /usr/lib/modules-load.d/
and installs both files.
* Generates DEBIAN/postinst that runs daemon-reload, enables the
service, triggers systemd-modules-load, and conditionally starts
the service iff /dev/daedalus-v4l2 is already present (uses the
same ConditionPathExists= guard as the unit file so apt install
doesn't fail loudly on a host where dkms hasn't built yet).
* Generates DEBIAN/prerm (stop + disable on remove) and
DEBIAN/postrm (daemon-reload).
debian/daedalus-v4l2-dkms:
* Lockstep version bump, PKGREL=1. Postinst (loud-warn-on-missing-
headers) unchanged.
Verified the SHA via local rev-parse against ~/src/daedalus-v4l2 —
481279c is the "packaging/systemd: ship daedalus-v4l2.service +
modules-load drop-in" commit on main.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
DKMS build for daedalus_v4l2 fails against kernel 6.18+ with:
daedalus_v4l2_main.c:1049: error: too few arguments to function
'v4l2_fh_add'
v4l2-fh.h:97: void v4l2_fh_add(struct v4l2_fh *fh, struct file *filp);
(same for v4l2_fh_del). Signature changed exactly at v6.18 — verified
v6.13–v6.17 still use the one-arg form via raw.githubusercontent.com
tag walk.
Upstream commit f0cd29a wraps the calls with LINUX_VERSION_CODE so the
module keeps building against:
* 6.12 LTS / RPi 6.12.75 (one-arg) — hertz
* 6.12.88+deb13-arm64 (one-arg)
* 6.18.29+rpt-rpi-2712 (file* arg) — higgs running kernel
Higgs (Pi CM5) was hitting this: daedalus-v4l2-dkms 0.1.0+r16+gf55b2cd
showed 'installed' in dpkg but DKMS autoinstall failed for the running
6.18.29 kernel. Re-running 'dkms autoinstall' after this bump succeeds
+ /dev/daedalus-v4l2 appears.
Also widens debian/daedalus-v4l2-dkms Recommends from
linux-headers-generic | linux-headers
to
linux-headers-rpi-2712 | linux-headers-rpi | linux-headers-generic | linux-headers
so apt pulls the right metapackage on Raspberry Pi OS / RPi-2712
kernels by default.
Userspace pkgver bumps in lockstep (no userspace change in f0cd29a, but
keeps daedalus-v4l2 + daedalus-v4l2-dkms versions matching for
LIBVA_DRIVER_NAME selection sanity).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The recipes pinned `f55b2cdab8a8c0bc04e8c1bb1d0b6ca85e7d96d2` as the
"Phase 8.13: byte-exact end-to-end via libva" commit, but that SHA
does not exist in git.reauktion.de/reauktion/daedalus-v4l2.
The actual `main` tip (per gitea's for-each-ref) is
`f55b2cd002afdfd08f3c093627317f92e4929074` — same 7-char prefix
(`f55b2cd`), different full hash. Likely a manually-constructed SHA
based on a short prefix from a working copy that was never pushed.
git archive --format=tar.gz on the bad SHA fails with
fatal: not a tree object: f55b2cdab8a8...
which surfaces as 500 from Gitea's archive endpoint, which curl in
the CI build-deb.sh sees as `curl: (22) ... error: 500`.
Diagnosed by tailing gitea.log during a fresh archive request from
the CI runner; the underlying `git archive` command in the gitea
container is logged with the full failing SHA + error.
Fixed in all four recipes (arch + debian, daedalus-v4l2 + dkms).
pkgrel bumped to signal new build (PKGVER short-prefix `gf55b2cd`
stays the same — both bad and good SHA share that prefix).
Stock Debian trixie ships FFmpeg 7.1 (libavcodec.so.61), our fork
ships FFmpeg 8.1 (libavcodec.so.62) — different SONAMEs, NOT a
drop-in for trixie's libavcodec61-consuming desktop. Previous
Conflicts: libavcodec61, libavformat61, ... triggered apt to remove
~50 packages (kde-plasma-desktop, vlc, dolphin, ...) when a user
just wanted ffmpeg-v4l2-request-fourier installed alongside.
This commit:
1. ffmpeg-v4l2-request-fourier (pkgrel=2):
- --prefix=/opt/fourier (instead of /usr)
- --extra-ldexeflags / --extra-ldsoflags: -Wl,-rpath,/opt/fourier/lib
so /opt/fourier/bin/ffmpeg finds its own libs without external help
- Ship /etc/ld.so.conf.d/fourier.conf with /opt/fourier/lib + ldconfig
in postinst/postrm. dlopen-by-SONAME consumers (firefox, daedalus)
find libavcodec.so.62 via ld.so cache without LD_LIBRARY_PATH.
- Drop ALL Conflicts/Replaces/Provides for libav* / libpostproc /
libsw* — no SONAME clash with stock libavcodec61, no reason to
evict anything.
- /usr/bin/ffmpeg-fourier + ffprobe-fourier convenience symlinks.
2. daedalus-v4l2 (pkgrel=2):
- Depends: ffmpeg-v4l2-request-fourier (>= 2:8.1+rfourier)
instead of stock 'ffmpeg (>= 7.1)'. The daedalus binary was
linked against libavcodec.so.62 at build time (CI runner had
marfrit/ffmpeg-v4l2-request-fourier installed); at runtime it
needs the .so.62 that only the fourier pkg provides.
Not touched:
- libva-v4l2-request-fourier: ships only v4l2_request_drv_video.so
at /usr/lib/<triplet>/dri/ which libva dlopens by file pattern.
Path A would break the lookup unless every consumer launcher sets
LIBVA_DRIVERS_PATH. Driver name is unique; no conflict. STAY.
- mpv-fourier: Depends already correctly bound to fourier ffmpeg.
Will receive libavcodec.so.62 via the ld.so.cache mechanism
above without recipe changes.
Two deterministic CI failures from run 115 (PR #34 wiring):
mpv-fourier-debian (task 566): dpkg-deb refuses `Conflicts: pkg1 |
pkg2` — Debian policy doesn't allow alternatives in Conflicts.
Split into separate entries.
daedalus-v4l2-debian (task 563): pacman -Syu pulled stock arch
ffmpeg which conflicts with the already-installed
ffmpeg-v4l2-request-fourier left behind by the earlier
mpv-fourier-aarch64 job (it configures [marfrit] + pre-installs
the fourier ffmpeg). Drop 'ffmpeg' from the pacman line; mirror
the [marfrit]+pre-install step from mpv-fourier-debian. Daedalus
only needs libavcodec/libavformat headers which the fourier
package supplies.
Mirror of arch/mpv-fourier into the Debian tree. Same source
pin (mpv 0.41.0), same 3 patches:
- 0001-meson-add-detection-logic-for-v4l2request-support.patch
- 0002-vo-hwdec-drmprime-add-separate-hwdecs-for-v4l2reques.patch
(Kwiboo + Langdale wiring for AV_HWDEVICE_TYPE_V4L2REQUEST
through drmprime VO hwdec — '--hwdec=v4l2request' actually
engages on dmabuf-wayland)
- 0001-vo_dmabuf_wayland-explicit-cache-sync-on-import-fd.patch
(iter1 of dmabuf-modifier-triage — explicit DMA_BUF_IOCTL_SYNC
on import fds; KWin-on-RK3566 dark-green chroma readback
regression fix on ohm. Root cause is the vb2_dma_resv RFC
upstream still pending.)
Depends on ffmpeg-v4l2-request-fourier (>= 2:8.1+rfourier) —
AV_HWDEVICE_TYPE_V4L2REQUEST only exists in Kwiboo's FFmpeg
fork; stock Debian ffmpeg doesn't have it.
Conflicts/Replaces stock mpv + libmpv2/libmpv1 — drop-in
replacement. Takes epoch 1.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Mirror of arch/ffmpeg-v4l2-request-fourier into the Debian tree.
Same source pin (Kwiboo v4l2-request-n8.1 @ b57fbbe), same 2
patches (libudev-bypass-fallback + nv15-to-p010-unpack), same
configure flag policy (drop X11/AMF/CUDA/Bluray/Vulkan/SDL2/etc.
per Fourier fleet focus).
Output: single .deb at /usr/bin/ffmpeg + /usr/bin/ffprobe +
/usr/lib/aarch64-linux-gnu/libav*.so.61. Conflicts/Replaces
the stock Debian ffmpeg + per-lib packages; takes epoch 2
(matches Debian's existing ffmpeg epoch).
Provides 'ffmpeg -hwaccel v4l2request' + '-hwaccel drm' routes
that drive rkvdec / hantro / cedrus / rpi-hevc-dec /
daedalus_v4l2 stateless decoders through libavcodec's hwdevice
DRM path, bypassing libva. Required by mpv-fourier and
firefox-fourier as their backing FFmpeg; also the kdirect
bit-exact reference for libva-v4l2-request-fourier validation.
NOT strictly required for the VAAPI-only path on
daedalus-v4l2 hosts (stock Debian ffmpeg + libva-v4l2-request-
fourier covers that). Install only when going firefox-fourier
or kdirect.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bumps all 4 daedalus packages (arch + debian × userspace + dkms)
to pick up daedalus-v4l2 f55b2cd: "kernel: media_request_get/put
around inf->req (UAF safety)".
Closes the SHIP-WITH-EYES-OPEN concern Sonnet flagged in the
pre-deployment review — without explicit media_request_get on
capture + media_request_put on completion, a concurrent
MEDIA_IOC_REQUEST_REINIT or process-kill triggering
buf_request_complete from the cancel path could drop vb2's
reference before our completion handler ran, leaving inf->req
dangling through v4l2_ctrl_request_complete + buf_done.
Matches the cedrus / rkvdec refcount pattern. No protocol
change, no API change, no consumer-side adjustment required.
Same byte-exact output verified on hertz post-fix (libva path:
match; standalone test_m2m_stream: 30/30 frames).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sonnet pre-deployment review caught a BLOCKER: on a fresh higgs
(Debian 13 / Pi CM5) install without the RPi kernel headers
pre-installed, the postinst's `dkms autoinstall || true` silently
swallowed the build failure. Package appeared installed but the
.ko was absent; `modprobe daedalus_v4l2` then failed and the
entire stack was dead with no clear pointer to the cause.
Fix in both ecosystems:
debian/daedalus-v4l2-dkms/build-deb.sh:
- After `dkms autoinstall`, verify the post-condition with
`dkms status -m daedalus_v4l2 -v VER -k $(uname -r)`.
- If the module isn't 'installed' / 'loaded' for the running
kernel, emit a yellow-bolded ANSI warning naming the most
likely cause (kernel headers package missing) and the exact
recovery steps (linux-headers-rpi-2712 for RPi or
linux-headers-$KERNELVER for Debian generic, then
`dkms autoinstall` + `modprobe`).
- Colour only on TTY; the warning is unconditional regardless.
arch/daedalus-v4l2-dkms/:
- New daedalus-v4l2-dkms.install with post_install +
post_upgrade hooks that run the same `dkms status` check.
- post_upgrade catches the case where a kernel-headers package
was uninstalled / pruned between upgrades, silently
regressing the build.
- Wired into the PKGBUILD via install="${pkgname}.install".
Both versions point at the actual repair commands rather than
just saying "build failed", so the user is one apt/pacman away
from a working stack instead of debugging dkms internals.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Mirror of arch/daedalus-v4l2-dkms into the Debian tree.
Architecture: all (source package — DKMS rebuilds per-kernel
at install time). Same pin (f04d700, Phase 8.13 close).
Installs kernel/ source to /usr/src/daedalus_v4l2-<ver>/ with
generated dkms.conf. postinst runs `dkms add` + `dkms
autoinstall` so the module builds against the running kernel's
headers automatically. prerm runs `dkms remove --all`.
Same Makefile-include-path flattening as the Arch sibling:
copies daedalus_v4l2_proto.h into kernel/include/ and patches
the Makefile's -I path.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Mirror of arch/daedalus-v4l2 into the Debian tree. Same pin
(f04d700, Phase 8.13 close), same install layout. Output as
arm64 .deb.
Build path: CMake for daemon (build via ninja); in-tree Makefile
for tools. No debhelper; standalone dpkg-deb so it builds on
the non-Debian runner.
Depends on ffmpeg (libavformat/libavcodec/libavutil 7.1+) at
runtime, libdrm2. Recommends daedalus-v4l2-dkms (the kernel
module).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Mirror of arch/libva-v4l2-request-fourier into the Debian tree.
Same pin (de27e95), same build (meson + ninja), output as
arm64 .deb installing the VA-API ICD as
/usr/lib/aarch64-linux-gnu/dri/v4l2_request_drv_video.so.
Auto-detected by VAAPI consumers (ffmpeg -hwaccel vaapi, mpv
--hwdec=vaapi, Firefox VAAPI accel) when
LIBVA_DRIVER_NAME=v4l2_request is set.
build-deb.sh follows the lmcp pattern: reproducible build with
SOURCE_DATE_EPOCH pin; standalone dpkg-deb so it runs on a
non-Debian builder without dh/debhelper.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Tracks upstream lmcp v1.1.1 (commit 9707f7a). Single-bug-fix
release: lmcp:tool() now normalises empty inputSchema.properties
by dropping the key, so Zod-strict MCP clients don't reject
tools/list with "expected: record, received: array".
Discovered live on a hertz-tools deployment where two custom
no-arg tools tripped the check and caused Claude Code to mark
the endpoint as disconnected.
New tarball sha256:
80c2e815aa61a2d3baab051c51cd247bdefa9dd03d72c4867b99c49b6eae9cb9
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The previous package bundled the agent prompt + skill cheatsheet, which leaked
home-infra topology (specific hosts/IPs, plug AINs, /opt/herding cred file
paths, kid/2FA context) to anyone with the public APT/pacman repo URL.
v0.2.0 ships only the plumbing:
- /usr/bin/claude-his-fetch (rsync runbook from $HIS_CONTEXT_HOST over SSH)
- /usr/bin/claude-his-install (symlinks cache -> ~/.claude/)
- /usr/share/doc/claude-his-agent/README.md
Runbook content lives at $HIS_CONTEXT_HOST:/opt/his-context/ (default hertz)
and gets fetched into ~/.cache/claude-his-agent/ on install. SSH key auth is
the trust boundary.
Adds rsync + openssh-client as runtime deps. Upstream sha256:
c39dd1a956d303ac2417498dde05ac923bf686f1fc978f78f0d63ca42432b8b8
Tag v0.1.3 added the scripts + quickref, v0.1.4 fixed doc paths.
Package both /usr/bin/repo-inventory.sh and /usr/bin/repo-inventory-nosudo.sh.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Claude Code Edit semantics — literal string replace with uniqueness
check. replace_all flag for bulk edits. Fixes missing edit tool on
lmcp-backed boltzmann / tesla / broglie.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- arch/claude-his-agent/PKGBUILD: fetches v0.1.0 tarball from
git.reauktion.de/marfrit/claude-his-agent, installs agent+skill+helper
to /usr/share/claude-agents/, /usr/share/claude-skills/his/, /usr/bin/
- debian/claude-his-agent/: control+changelog+copyright + build-deb.sh
mirroring the lmcp-debian pattern (dpkg-deb, reproducible mtimes)
- .gitea/workflows/build.yml: two new serialized jobs (claude-his-any +
claude-his-debian) after lmcp-debian; same publish flow as lmcp.
reprepro refuses to re-include a .deb if the bytes differ from one
already in pool/. Fixed mtimes via SOURCE_DATE_EPOCH make subsequent
builds byte-identical, so CI re-runs of the same pkgver/pkgrel are
accepted as no-ops instead of failing.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- debian/lmcp/build-deb.sh fetches the v0.3.0 tarball, lays out the
filetree, and uses dpkg-deb to assemble lmcp_0.3.0-1_all.deb directly
on the Arch aarch64 runner (no debhelper needed for a pure-Lua pkg).
- workflow job 'lmcp-debian' rsyncs the .deb to hertz's marfritrepo
incoming dir, then ssh-triggers 'publish-deb <suite>' for both
bookworm and trixie. publish-deb wraps 'reprepro includedeb' and
rsyncs dists/+pool/ to nc.
- New secret MARFRIT_REPO_HERTZ_KEY uploaded to Gitea repo. Forced
command on hertz routes rsync uploads vs publish-deb triggers.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>