32 Commits

Author SHA1 Message Date
Claude (noether) 7d6a5a601e sic 0.2.1: fix the v2 stdin hang (sicd reaps on child-exit)
sicd + sic-agent -> 0.2.1-1 against sic tag v0.2.1 (tarball sha 0efe5acc…). The daemon fix: it
no longer blocks the stdin pump after the child exits, so sic calls with a never-EOFing stdin
(non-interactive callers holding the pipe open) return promptly instead of hanging to a timeout.
Client unchanged. Pre-flight built (debian amd64 + arch verifysource).
2026-07-23 19:27:41 +02:00
Claude (noether) c694fc93f7 ci: unblock sic jobs — sicd-arch needed a job on the DEAD debian-aarch64 runner
The four sic jobs (sicd/sic-agent x arch/debian, all runs-on arch-aarch64) have NEVER
run since they were added 2026-07-19. Root cause: sicd-arch (head of the chain) had
needs: daedalus-v4l2-dkms-debian -- a job on the debian-aarch64 runner (bohr), which is
offline/unregistered. Every debian-aarch64 job skips, so sicd-arch was blocked forever,
cascading to the whole sic chain. The dependency was spurious (sic has nothing to do with
a v4l2 DKMS build); it only existed to serialize on the single arch runner, but was pinned
to the wrong chain tail. Re-point to reauktion-home-ca-debian (a leaf on the WORKING
arch-aarch64 runner) -- same serialization discipline, off the dead runner. Upstream keeps
continue-on-error, so sic runs regardless of that job's result.

This is what let 0.2.0 (and every prior sic push) silently publish nothing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 12:42:22 +02:00
Claude (noether) 522f9c0364 sic 0.2.0: nested targets + v2 argv-boundary wire (dual-read, backward compatible)
Bumps sicd + sic-agent (arch PKGBUILDs, debian build-deb.sh, both changelogs) to
0.2.0-1 against sic tag v0.2.0 (tarball sha fe0569013da5...). New tarball verified
building all four packages locally (debian amd64 debs + arch verifysource) before push.

What 0.2.0 ships (source git.reauktion.de/marfrit/sic @ 4fcd851):
  * Nested targets: sic host/hop1/hop2 cmd peels incus/docker/pct container hops,
    resolved via /etc/sic/hosts.toml, built as a netstring onion.
  * argv boundaries preserved end to end (length-framed [][]byte, never space-split)
    -- the founding guarantee: sic host touch 'a b' stays ONE file.
  * Daemon dual-reads v1 and v2 (first-byte dispatch), so pre-0.2.0 clients keep
    working during the staged rollout.
  * Client forwards stdin AFTER the frame (fixes the v0.1.0 zero-byte trap), ssh -T
    binary-safe, exit status inherited.
  * Hardened + reviewed (bullpen 964/970): outer-length cap before alloc, per-element
    and byte caps, explicit canonical argc (empty "" args representable).

Also removes continue-on-error from the four sic CI jobs (sicd/sic-agent x arch/debian)
so a broken build fails the workflow loudly instead of silently producing nothing --
the reason the sic jobs went unnoticed as never-succeeding since 2026-07-19.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 12:15:46 +02:00
marfrit 748b2fb3e9 reauktion-home-ca: bump pkgrel to 2 — force a real dual-arch publish
pkgrel 1 was already live on arch/aarch64 (last-modified 2026-07-18, from
an untracked prior attempt, not committed to git). check-already-published.sh
only ever probes the aarch64 pool, so with pkgrel 1 my CI job saw
skip=1 and never ran its build/sign/publish steps at all — meaning
x86_64 never got the package. Bumping pkgrel forces a genuine rebuild
through the full dual-arch publish path, and the publish step's
repo-remove-then-add also retires the stale untracked -1 db entry.
2026-07-20 10:59:46 +02:00
marfrit 7669ac2bb1 reauktion-home-ca: decouple from the sic-agent-debian tail
sic-agent-debian sits behind daedalus-v4l2-dkms-debian -> daedalus-v4l2-debian,
which needs the debian-aarch64 runner (actrunner-debian-aarch64-bohr) -
currently offline (bohr container stopped on boltzmann). reauktion-home-ca
doesn't need that runner at all (both its jobs run on arch-aarch64), so
chain it after aish-debian instead of waiting on an unrelated stuck runner.
2026-07-20 10:54:25 +02:00
marfrit 07b4d5383e reauktion-home-ca: add Arch + Debian packaging and CI publish jobs
The package was referenced in memory as already published but never
actually existed in this repo or on packages.reauktion.de — only an
unpublished Arch build was staged on hertz. Adds real PKGBUILD +
dpkg-deb packaging (cert committed alongside, no upstream tarball)
and wires both into build.yml following the lmcp/aish dual-arch +
debian publish pattern.
2026-07-20 10:35:43 +02:00
Markus Fritsche 108fc4fba7 sic: add sicd + sic-agent packages (Arch + Debian) + CI
sicd (daemon, target hosts) and sic-agent (client + agent skills) from
git.reauktion.de/marfrit/sic v0.1.0. Go binaries, cross-built with GOARCH.

- arch/sicd, arch/sic-agent: PKGBUILDs (build from source via go).
- debian/sicd, debian/sic-agent: control/copyright/changelog + build-deb.sh
  (per-arch amd64/arm64).
- .gitea/workflows/build.yml: 4 jobs — Arch aarch64 (repo-signed, -> nc) and
  Debian amd64+arm64 (-> hertz reprepro, bookworm+trixie). continue-on-error,
  chained after the existing jobs.

Validated locally: Arch aarch64 pkgs + Debian arm64/amd64 debs build; the
packaged sicd binary runs (netstring exec).
2026-07-19 12:33:23 +02:00
marfrit 5716775f91 Merge pull request 'lmcp/debian: fix build-deb.sh sha256 for v1.2.4 (finish the release, for real)' (#113) from claude-noether/marfrit-packages:lmcp-1.2.4-debsha into main
Reviewed-on: marfrit/marfrit-packages#113
2026-07-12 21:46:42 +00:00
claude-noether 422346843d lmcp/debian: fix build-deb.sh LMCP_TARBALL_SHA256 for v1.2.4
PR #112 bumped PKGVER/UPSTREAM_TAG to 1.2.4 but left LMCP_TARBALL_SHA256 at the
1.2.3 hash, so the sha256 -c check failed on the v1.2.4 tarball and lmcp-debian
errored. Update the pinned hash to the v1.2.4 archive.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-12 23:44:24 +02:00
marfrit c7d0d5ed7b Merge pull request 'lmcp/debian: bump build-deb.sh to 1.2.4 (finish the release)' (#112) from claude-noether/marfrit-packages:lmcp-1.2.4-debfix into main
Reviewed-on: marfrit/marfrit-packages#112
2026-07-12 21:39:20 +00:00
claude-noether 9621d939bb lmcp/debian: bump build-deb.sh to 1.2.4 (PKGVER + UPSTREAM_TAG)
The 1.2.4 changelog was bumped but build-deb.sh still pinned PKGVER=1.2.3 /
UPSTREAM_TAG=v1.2.3, so check-already-published saw 1.2.3 in the pool and the
lmcp-debian job skipped without publishing 1.2.4. Bump both so the .deb builds
against the v1.2.4 tag.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-12 23:14:15 +02:00
marfrit 2cc5f5283f Merge pull request 'lmcp: bump to 1.2.4 (shell timeout-kill fix + kill_job/list_jobs)' (#111) from claude-noether/marfrit-packages:lmcp-1.2.4 into main
Reviewed-on: marfrit/marfrit-packages#111
2026-07-12 21:09:53 +00:00
claude-noether 75046ee3bc lmcp: bump to 1.2.4 (shell timeout-kill fix + kill_job/list_jobs)
Ships marfrit/lmcp v1.2.4: shell/shell_bg kills the whole process group on
timeout/cancel (no orphans) + new kill_job/list_jobs tools. Updates arch
PKGBUILD (pkgver + sha256) and debian changelog.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-12 23:05:38 +02:00
marfrit e2991ff55b linux-pinetab2-danctnix-besser: re-enable CONFIG_SHADOW_CALL_STACK
GCC 16.1.1 fixed the arm_neon.h #pragma target + SCS interaction.
The cumulative patch already had a CFLAGS_xor-neon.o workaround.
Verified on boltzmann with GCC 16.1.1 (test build exit code 0).

Closes #20
2026-07-10 07:50:53 +00:00
Markus Fritsche 41383e402c ffmpeg-v4l2-request-fourier: bump pkgrel 15->16 (rebuild against libx265.so=216) 2026-06-22 21:34:01 +02:00
marfrit 399a34955d lmcp: update changelog for 1.2.3 2026-06-05 15:58:27 +00:00
marfrit c6270a5f77 lmcp: bump to 1.2.3 — add nash memory tools plugin 2026-06-05 15:58:06 +00:00
marfrit 66643c2ab1 lmcp: bump to 1.2.3 — add nash memory tools plugin 2026-06-05 15:57:54 +00:00
marfrit eae92c2b82 Merge pull request 'lmcp: bump to 1.2.2 — case-insensitive Bearer auth (marfrit/lmcp#25)' (#109) from williams/marfrit-packages:williams/bump-lmcp-1.2.2 into main
Reviewed-on: marfrit/marfrit-packages#109
2026-05-30 14:54:38 +00:00
marfrit c1e0add187 lmcp: bump to 1.2.2 — case-insensitive Bearer auth (marfrit/lmcp#25) 2026-05-30 14:52:35 +00:00
marfrit 9b0cb71370 Merge pull request 'ffmpeg-v4l2-request-fourier: export ff_h264_set_mb_inspect_cb (0016 amend, PKGREL 15)' (#108) from claude-noether/marfrit-packages:noether/h264-mb-inspect-export-symbol into main
Reviewed-on: marfrit/marfrit-packages#108
2026-05-26 14:54:27 +00:00
marfrit 25610930ad ffmpeg-v4l2-request-fourier: export ff_h264_set_mb_inspect_cb (0016 amend, PKGREL 15)
The 0016 patch declared ff_h264_set_mb_inspect_cb in h264dec.h and
defined it in h264_mb.c, but didn't touch libavcodec/libavcodec.v.
FFmpeg's default version script exports only `av_*`, `avcodec_*`,
`avpriv_*`, and `avsubtitle_free`; everything else is hidden as LOCAL
behind a `*` glob.  Result: `nm -D libavcodec.so.62 | grep
ff_h264_set_mb_inspect_cb` returned nothing → dlsym() returned NULL.

Static-link CLI consumer (daedalus_decode_h264) was unaffected
because static linking doesn't care about symbol visibility.  The
daedalus-v4l2 daemon shadow_decoder path (PR-Q3a.1) dlopens
libavcodec.so.62 and resolves the callback via dlsym — that needs
the symbol exported.

Fix: add ff_h264_set_mb_inspect_cb to the global list in
libavcodec/libavcodec.v.  Single-line addition to the 0016 patch.
Mirrored across the arch/ + debian/ patch trees.

PKGREL bump 14 → 15, changelog entry added (debian side).  PKGBUILD
pkgrel bumped on arch side too.  No behaviour change to the decode
path: the callback is still opt-in via the H264Context function
pointer; only consumers that have explicitly installed a callback
pay the one-load-one-branch cost per MB.

dejavu-check: this is fixing the existing 0016 observation-hook to
actually work as a dlsym intercept (the architectural shape the
patch was designed for).  NOT adding new per-kernel substitution.
Same shape, same patch number, same intent.  Just hiding/exporting
plumbing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 15:38:03 +02:00
marfrit 368fcff41f Merge pull request 'ffmpeg-v4l2-request-fourier: preserve sl->mb for inspection callback (0017)' (#107) from claude-noether/marfrit-packages:noether/h264-mb-coeffs-side-buffer into main
Reviewed-on: marfrit/marfrit-packages#107
2026-05-26 07:48:47 +00:00
claude-noether ea99dc8e27 ffmpeg-v4l2-request-fourier: preserve sl->mb for inspection callback (0017)
Companion to 0016 (PR #106).  Adds a coefficient side buffer in
H264Context, populated at the start of ff_h264_hl_decode_mb with a
single memcpy from sl->mb BEFORE IDCT-add zeros it.  The existing
post-pixel-work callback (still in 0016) can now read:
  - h->mb_inspect_coeffs  = pre-IDCT coefficients (this patch)
  - h->cur_pic.f->data    = post-pixel-work pre-deblock reconstruction

and derive P = pixels − IDCT(C) for daedalus-decoder's frame-major
dispatch in PR-A3+.

Memcpy gated on (h->mb_inspect_cb != NULL).  Zero cost when no
consumer is registered.  Side buffer = 16 * 48 int16 = 1536 bytes
(matches the 8-bit half of sl->mb's int16_t[16 * 48 * 2] declared
size; high-bit-depth uses the upper half — not preserved here since
the daedalus-decoder consumer is 8-bit-only).

Single-threaded decode assumed at the consumer side
(avctx->thread_count = 1).  Multi-slice / multi-threaded streams
would race on the single side buffer — explicit limitation of the
inspection mechanism, future extension would put per-slice buffers
in H264SliceContext.

Verified: patches 0016 + 0017 apply cleanly and build in sequence
against the Kwiboo v4l2-request-n8.1 fork at the pinned commit
b57fbbe5.  ff_h264_set_mb_inspect_cb symbol exported as before.

Wired into arch PKGBUILD + debian build-deb.sh patch sequence.
pkgrel bumped 13 → 14.

Refs reauktion/daedalus-decoder!14 (PR-A2 callback wiring complete,
PR-A3 coefficient extraction is the next consumer).
2026-05-26 09:46:10 +02:00
marfrit 59901bceca Merge pull request 'ffmpeg-v4l2-request-fourier: per-MB inspection callback for H.264 (0016)' (#106) from claude-noether/marfrit-packages:noether/h264-mb-inspect-callback into main
Reviewed-on: marfrit/marfrit-packages#106
2026-05-26 04:05:57 +00:00
claude-noether 87cbb9b70a ffmpeg-v4l2-request-fourier: per-MB inspection callback for H.264 (0016)
Adds 0016-h264-mb-inspect-callback.patch to the FFmpeg fork.  Adds an
opt-in callback fired by ff_h264_hl_decode_mb after the existing
pixel work, for tools that need per-MB visibility into H.264 decode.

API:
  typedef void (*ff_h264_mb_inspect_cb)(void *opaque,
                                         const struct H264Context *h,
                                         int mb_x, int mb_y);
  void ff_h264_set_mb_inspect_cb(AVCodecContext *avctx,
                                  ff_h264_mb_inspect_cb cb, void *opaque);

Two new fields appended to H264Context (internal struct, declared in
h264dec.h not h264.h, no ABI surface to non-libavcodec callers).
Callback fires post-pixel-work for every MB in coded order; receives
const H264Context* so it can inspect any state (slice ctx via
h->slice_ctx, reconstructed pixels via h->cur_pic.f->data[plane],
etc.).

Default (cb==NULL): zero behaviour change, one load + one branch per
MB in the decoder hot path.

Shape distinction: per-MB observation, NOT per-kernel function-pointer
hijack (the 0003-0014 substitution-arc pattern that PR #105 reverted
+ daedalus-fourier PR #37's measurement-correction architecturally
retired).  Per-block synchronous Vulkan dispatch from libavcodec is
non-competitive; per-MB CPU-side observation feeding a per-frame
daedalus-decoder batch submit is the right shape (frame-major UMA
dispatch verdict, memory: dejavu).

Used by:
  - daedalus-decoder/tools/daedalus_decode_h264 (PR-A1b, follow-up)
  - future daedalus-v4l2 daemon refactor

Wired into arch PKGBUILD source[] + prepare() and debian build-deb.sh
patch sequence.  pkgrel bumped 12 → 13.

Refs reauktion/daedalus-decoder!12.
2026-05-26 05:57:49 +02:00
marfrit bdf3fffe2d Merge pull request 'ffmpeg-v4l2-request-fourier: revert ctx flip — PR #36 was a measurement artifact (0015)' (#105) from claude-noether/marfrit-packages:noether/revert-h264-ctx-qpu-capable into main
Reviewed-on: marfrit/marfrit-packages#105
2026-05-25 20:33:52 +00:00
claude-noether f4047f3145 ffmpeg-v4l2-request-fourier: revert ctx flip — PR #36 was a measurement artifact (0015)
Reverts the no_qpu → qpu-capable ctx flip that landed via patch 0014
(marfrit-packages PR #104).

PR #104 was justified by daedalus-fourier PR #36's "QPU 4.30x faster
than CPU NEON" bench result.  That number was a measurement artifact:
v3d_runner.read_spv() did a bare cwd-relative fopen() with no path
search, so when the bench was run from the source dir (as in PR #36),
the SPVs at $builddir/v3d_*.spv were not found, every QPU dispatch
returned -1 fast, and the bench loop timed the failure path.

daedalus-fourier PR #37 fixes the SPV search + bench preflight.
Corrected numbers on hertz (Pi 5 V3D 7.1):

  kernel             CPU ns/op  QPU ns/op  winner
  IDCT 4x4 luma          10.75     217.63  CPU 20.24x
  IDCT 8x8 luma          29.69     785.94  CPU 26.47x
  Deblock luma_v         17.63     467.42  CPU 26.51x
  Deblock luma_h         38.30     498.53  CPU 13.02x
  qpel mc20 (8x8)        30.17    1300.44  CPU 43.10x
  qpel mc02 (8x8)        17.69    1363.40  CPU 77.08x
  qpel mc22 (8x8)        71.60    1948.37  CPU 27.21x

  1080p sum: CPU 5.57 ms vs QPU 123.54 ms — QPU 22x SLOWER.

Until daedalus QPU dispatch overhead is actually competitive (separate
multi-task effort tracked on the daedalus-fourier side), libavcodec.so
substitution must stay on daedalus_ctx_create_no_qpu() so the host
processes (firefox-fourier RDD, mpv-fourier, daedalus_v4l2_daemon)
don't pessimize their H.264 decode path.

Adds 0015-h264-ctx-revert-to-no-qpu.patch (2-line revert of patch 0014)
to both arch PKGBUILD and debian build-deb.sh.  Both pkgrel bumped
11 → 12.  Refs reauktion/daedalus-fourier!37.
2026-05-25 21:47:33 +02:00
marfrit 190f810843 Merge pull request 'ffmpeg-v4l2-request-fourier: flip libavcodec daedalus ctx no_qpu → qpu-capable (0013)' (#104) from claude-noether/marfrit-packages:noether/h264-ctx-qpu-capable into main
Reviewed-on: marfrit/marfrit-packages#104
2026-05-25 19:25:30 +00:00
claude-noether 9c70ffffe7 ffmpeg-v4l2-request-fourier: flip libavcodec daedalus ctx no_qpu → qpu-capable (0014)
(Renumbered from 0013 — PR #102 landed 0013-h264-deblock-chroma-intra
while this PR was open, so the next free slot is 0014.)

Patches 0003 (IDCT 4x4) and 0007 (qpel mc20) created the libavcodec.so
process-global daedalus_ctx via daedalus_ctx_create_no_qpu().  Rationale
at the time: cycle 6/9 had only CPU NEON paths, so a QPU-capable ctx
would have meant pointless Vulkan init in every host process.

Two things changed since:

  1. Every H.264 hot-path primitive now has a V3D7 compute shader.
     IDCT 4x4/8x8 + 8 deblock variants (luma+chroma × V+H × inter+intra)
     + 30 qpel positions.  See daedalus-fourier PRs #28-#35.

  2. Dispatch overhead has been hammered down — buffer pool in
     v3d_runner + persistent command buffer.  daedalus-fourier PR #36
     bench on hertz (Pi 5 V3D 7.1, 30 iters x 5 warmup):

       1080p worst-case sum (IDCT4 + deblock luma + qpel mc22):
         CPU NEON only:  5.57 ms
         QPU only:       1.30 ms   (CPU/QPU sum ratio = 4.30x)

PR #10's CPU-4x-faster-than-QPU verdict (which justified the original
no_qpu ctx choice) is reversed by ~17x.

This commit adds 0014-h264-ctx-qpu-capable.patch which flips both H.264
TUs (h264_idct_daedalus.c, h264_qpel_daedalus.c) from
daedalus_ctx_create_no_qpu() to daedalus_ctx_create().

daedalus_ctx_create() probes for a usable Vulkan device and falls back
to no_qpu mode if unavailable, so this is safe on hosts without V3D
(x86 build runners, Debian aarch64 builders without renderD, etc.).
Hosts WITH V3D (Pi 5 deployment targets) now route the H.264 hot-path
through V3D compute instead of CPU NEON.

Wired into both arch PKGBUILD (source[] + prepare()) and debian
build-deb.sh; both pkgrel bumped 10 → 11.

Refs reauktion/daedalus-fourier!36.
2026-05-25 21:18:18 +02:00
marfrit 520f2fce33 Merge pull request 'mesa-panvk-bifrost r9: bump maxImageDimension3D to 2048 (iter22, unblocks Dawn/WebGPU)' (#103) from claude-noether/marfrit-packages:mesa-panvk-bifrost-r9 into main
Reviewed-on: marfrit/marfrit-packages#103
2026-05-25 18:17:16 +00:00
marfrit e323aa2316 mesa-panvk-bifrost r9: bump maxImageDimension3D to 2048 (iter22, unblocks Dawn/WebGPU)
Adds 0008-panvk-bifrost-bump-max-image-dim-3d-for-dawn.patch. Two-hunk patch:

Hunk 1: Bumps maxImageDimension3D from 512 to 2048 on Bifrost (PAN_ARCH 7..10).
Surfaced by panvk-bifrost-perf-measurement iter1 spike: Brave's WebGPU/Dawn
detects panvk-bifrost as a Vulkan adapter on Mali-G52 r1 MC1 but rejects it
because the advertised limit is below WebGPU's 2048 minimum (per
third_party/dawn/src/dawn/native/vulkan/PhysicalDeviceVk.cpp:746). This is
the actual unblock for the campaign's stated motivator — Chromium GPU
process Vulkan boot on PineTab2 / Bifrost SBCs.

Per Vulkan 1.3 spec §43.1, maxImageDimensionXD is the upper bound on any
creatable image; per-format limits MAY be smaller. On PAN_ARCH<=10 the
per-format limit caps at ~1023 per axis for RGBA8 within the 4 GB
max_img_size_B address constraint. Apps trying 2048^3 with thick formats
hit the per-format limit at image-create — per-spec behavior.

Hunk 2: Removes three asserts in get_max_3d_image_size() that encoded the
wrong invariant (per-format >= basic), opposite of what the Vulkan spec
mandates. The asserts were release-mode-masked via NDEBUG, but debug
builds would abort the first time Dawn (or any client) called
vkGetPhysicalDeviceImageFormatProperties on a 3D image format. Surfaced
by Phase 5 2nd-model review.

Verified on PineTab2 (Mali-G52 r1 MC1, PAN_ARCH 7):
  - vulkaninfo: maxImageDimension3D = 2048
  - Brave/Dawn: "Insufficient Vulkan limits" warning eliminated; adapter
    accepted for WebGPU.
  - CTS regression: dEQP-VK.api.copy_and_blit.core.image_to_image.3d_images.*
    6/6 Pass (unchanged from r7 baseline).

Phase 5 (2nd-model) review: APPROVE WITH CHANGES — both changes applied
(release-mode + debug-mode assert exposure addressed by removing the
wrong-invariant asserts).

Note on numbering: r8 was attempted (KHR_depth_clamp_zero_one trim) but
abandoned mid-Phase-3 when it surfaced that 5 more post-1.3.10 KHR
extensions are advertised — surgically false-gating all of them would
risk undoing r1's KHR_robustness2 work for Chromium Dawn. Documented at
~/src/panvk-bifrost/iter21/phase0to3_close_no_ship.md.

Cross-refs:
  - ~/src/panvk-bifrost/iter22/phase0to2_max3d_close.md (Phase 0-2 close)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-25 15:54:18 +02:00
40 changed files with 1950 additions and 29 deletions
+445
View File
@@ -1732,3 +1732,448 @@ jobs:
if: always()
run: rm -f /root/.ssh/id_ed25519_hertz
# ===========================================================================
# sic — quoting-proof remote command execution (git.reauktion.de/marfrit/sic).
# Two packages: sicd (daemon, target hosts) and sic-agent (client + skills).
# Go binaries -> arch-specific. Arch: aarch64 (the Arch fleet is aarch64).
# Debian: amd64 + arm64 (the Debian/Proxmox hosts span both). Cross-built with
# Go's GOARCH on the aarch64 runner.
# ===========================================================================
sicd-arch:
needs: reauktion-home-ca-debian
runs-on: arch-aarch64
steps:
- uses: actions/checkout@v4
- name: bootstrap runner (idempotent)
run: |
set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
retry pacman -Syu --noconfirm --needed base-devel git rsync gnupg openssh sudo go
- name: import signing key
env:
PRIV: ${{ secrets.MARFRIT_REPO_PRIVATE_KEY }}
PASS: ${{ secrets.MARFRIT_REPO_PASSPHRASE }}
run: |
set -e
gpgconf --homedir /root/.gnupg --kill all 2>/dev/null || true
rm -rf /root/.gnupg /root/repo_pass
mkdir -m700 -p /root/.gnupg
printf '%s' "$PASS" > /root/repo_pass
chmod 600 /root/repo_pass
printf '%s\n' "$PRIV" | gpg --batch --import
echo "92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C:6:" | gpg --import-ownertrust
- name: install deploy ssh key
env:
KEY: ${{ secrets.MARFRIT_REPO_DEPLOY_KEY }}
run: |
mkdir -m700 -p /root/.ssh
printf '%s\n' "$KEY" > /root/.ssh/id_ed25519
chmod 600 /root/.ssh/id_ed25519
ssh-keyscan -t ed25519 nc.reauktion.de > /root/.ssh/known_hosts 2>/dev/null
- name: makepkg sicd
run: |
set -e
rm -rf /tmp/build-sicd
cp -r arch/sicd /tmp/build-sicd
chown -R builder:builder /tmp/build-sicd
cd /tmp/build-sicd
sudo -u builder -H makepkg --nocheck --noconfirm --syncdeps --cleanbuild
ls -la *.pkg.tar.* | grep -v "\.sig$"
- name: sign sicd
run: |
set -e
cd /tmp/build-sicd
for f in *.pkg.tar.xz *.pkg.tar.zst *.pkg.tar.gz; do
[ -f "$f" ] || continue
gpg --batch --pinentry-mode loopback --passphrase-file /root/repo_pass \
--detach-sign --yes -u 92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C "$f"
done
- name: update aarch64 repo db
run: |
set -e
mkdir -p /tmp/arch-stage-sicd
cd /tmp/arch-stage-sicd
rm -f *
for f in marfrit.db.tar.gz marfrit.db.tar.gz.sig marfrit.files.tar.gz marfrit.files.tar.gz.sig; do
curl -sSLf "https://packages.reauktion.de/arch/aarch64/$f" -o "$f" || rm -f "$f"
done
for ext in xz zst gz; do
ls /tmp/build-sicd/*.pkg.tar.$ext 2>/dev/null && \
mv /tmp/build-sicd/*.pkg.tar.$ext /tmp/build-sicd/*.pkg.tar.$ext.sig .
done || true
export GNUPGHOME=/root/.gnupg
printf 'pinentry-mode loopback\npassphrase-file /root/repo_pass\n' > /root/.gnupg/gpg.conf
printf 'allow-loopback-pinentry\n' > /root/.gnupg/gpg-agent.conf
gpg-connect-agent reloadagent /bye
pkgs=()
for ext in xz zst gz; do
for f in *.pkg.tar.$ext; do [ -f "$f" ] && pkgs+=("$f"); done
done
if [ -f marfrit.db.tar.gz ]; then
for f in "${pkgs[@]}"; do
name=$(echo "$f" | sed -E 's/-[0-9].*//')
repo-remove --sign --key 92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C \
marfrit.db.tar.gz "$name" 2>/dev/null || true
done
fi
repo-add --new --sign --key 92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C \
--verify marfrit.db.tar.gz "${pkgs[@]}"
ln -sf marfrit.db.tar.gz marfrit.db
ln -sf marfrit.files.tar.gz marfrit.files
ln -sf marfrit.db.tar.gz.sig marfrit.db.sig
rm -f marfrit.files.sig
- name: publish to aarch64
run: |
set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
cd /tmp/arch-stage-sicd
retry rsync -avL --copy-unsafe-links -e 'ssh -i /root/.ssh/id_ed25519' \
./ mfritsche@nc.reauktion.de:arch/aarch64/
- name: wipe secrets
if: always()
run: rm -f /root/repo_pass /root/.ssh/id_ed25519
sic-agent-arch:
needs: sicd-arch
runs-on: arch-aarch64
steps:
- uses: actions/checkout@v4
- name: bootstrap runner (idempotent)
run: |
set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
retry pacman -Syu --noconfirm --needed base-devel git rsync gnupg openssh sudo go
- name: import signing key
env:
PRIV: ${{ secrets.MARFRIT_REPO_PRIVATE_KEY }}
PASS: ${{ secrets.MARFRIT_REPO_PASSPHRASE }}
run: |
set -e
gpgconf --homedir /root/.gnupg --kill all 2>/dev/null || true
rm -rf /root/.gnupg /root/repo_pass
mkdir -m700 -p /root/.gnupg
printf '%s' "$PASS" > /root/repo_pass
chmod 600 /root/repo_pass
printf '%s\n' "$PRIV" | gpg --batch --import
echo "92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C:6:" | gpg --import-ownertrust
- name: install deploy ssh key
env:
KEY: ${{ secrets.MARFRIT_REPO_DEPLOY_KEY }}
run: |
mkdir -m700 -p /root/.ssh
printf '%s\n' "$KEY" > /root/.ssh/id_ed25519
chmod 600 /root/.ssh/id_ed25519
ssh-keyscan -t ed25519 nc.reauktion.de > /root/.ssh/known_hosts 2>/dev/null
- name: makepkg sic-agent
run: |
set -e
rm -rf /tmp/build-sic-agent
cp -r arch/sic-agent /tmp/build-sic-agent
chown -R builder:builder /tmp/build-sic-agent
cd /tmp/build-sic-agent
sudo -u builder -H makepkg --nocheck --noconfirm --syncdeps --cleanbuild
ls -la *.pkg.tar.* | grep -v "\.sig$"
- name: sign sic-agent
run: |
set -e
cd /tmp/build-sic-agent
for f in *.pkg.tar.xz *.pkg.tar.zst *.pkg.tar.gz; do
[ -f "$f" ] || continue
gpg --batch --pinentry-mode loopback --passphrase-file /root/repo_pass \
--detach-sign --yes -u 92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C "$f"
done
- name: update aarch64 repo db
run: |
set -e
mkdir -p /tmp/arch-stage-sic-agent
cd /tmp/arch-stage-sic-agent
rm -f *
for f in marfrit.db.tar.gz marfrit.db.tar.gz.sig marfrit.files.tar.gz marfrit.files.tar.gz.sig; do
curl -sSLf "https://packages.reauktion.de/arch/aarch64/$f" -o "$f" || rm -f "$f"
done
for ext in xz zst gz; do
ls /tmp/build-sic-agent/*.pkg.tar.$ext 2>/dev/null && \
mv /tmp/build-sic-agent/*.pkg.tar.$ext /tmp/build-sic-agent/*.pkg.tar.$ext.sig .
done || true
export GNUPGHOME=/root/.gnupg
printf 'pinentry-mode loopback\npassphrase-file /root/repo_pass\n' > /root/.gnupg/gpg.conf
printf 'allow-loopback-pinentry\n' > /root/.gnupg/gpg-agent.conf
gpg-connect-agent reloadagent /bye
pkgs=()
for ext in xz zst gz; do
for f in *.pkg.tar.$ext; do [ -f "$f" ] && pkgs+=("$f"); done
done
if [ -f marfrit.db.tar.gz ]; then
for f in "${pkgs[@]}"; do
name=$(echo "$f" | sed -E 's/-[0-9].*//')
repo-remove --sign --key 92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C \
marfrit.db.tar.gz "$name" 2>/dev/null || true
done
fi
repo-add --new --sign --key 92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C \
--verify marfrit.db.tar.gz "${pkgs[@]}"
ln -sf marfrit.db.tar.gz marfrit.db
ln -sf marfrit.files.tar.gz marfrit.files
ln -sf marfrit.db.tar.gz.sig marfrit.db.sig
rm -f marfrit.files.sig
- name: publish to aarch64
run: |
set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
cd /tmp/arch-stage-sic-agent
retry rsync -avL --copy-unsafe-links -e 'ssh -i /root/.ssh/id_ed25519' \
./ mfritsche@nc.reauktion.de:arch/aarch64/
- name: wipe secrets
if: always()
run: rm -f /root/repo_pass /root/.ssh/id_ed25519
sicd-debian:
needs: sic-agent-arch
runs-on: arch-aarch64
steps:
- uses: actions/checkout@v4
- name: install deps
run: |
set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
retry pacman -Syu --noconfirm --needed dpkg openssh rsync curl go
- name: install hertz deploy ssh key
env:
KEY: ${{ secrets.MARFRIT_REPO_HERTZ_KEY }}
run: |
mkdir -m700 -p /root/.ssh
printf '%s\n' "$KEY" > /root/.ssh/id_ed25519_hertz
chmod 600 /root/.ssh/id_ed25519_hertz
ssh-keyscan -t ed25519 hertz.fritz.box >> /root/.ssh/known_hosts 2>/dev/null
- name: build + publish sicd .deb (amd64 + arm64)
run: |
set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
cd debian/sicd
for arch in amd64 arm64; do
./build-deb.sh "$arch"
DEB=$(ls sicd_*_${arch}.deb | head -1)
retry rsync -av -e 'ssh -i /root/.ssh/id_ed25519_hertz' "$DEB" \
marfritrepo@hertz.fritz.box:
for suite in bookworm trixie; do
retry ssh -i /root/.ssh/id_ed25519_hertz marfritrepo@hertz.fritz.box \
"publish-deb $suite $DEB"
done
done
- name: wipe secrets
if: always()
run: rm -f /root/.ssh/id_ed25519_hertz
sic-agent-debian:
needs: sicd-debian
runs-on: arch-aarch64
steps:
- uses: actions/checkout@v4
- name: install deps
run: |
set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
retry pacman -Syu --noconfirm --needed dpkg openssh rsync curl go
- name: install hertz deploy ssh key
env:
KEY: ${{ secrets.MARFRIT_REPO_HERTZ_KEY }}
run: |
mkdir -m700 -p /root/.ssh
printf '%s\n' "$KEY" > /root/.ssh/id_ed25519_hertz
chmod 600 /root/.ssh/id_ed25519_hertz
ssh-keyscan -t ed25519 hertz.fritz.box >> /root/.ssh/known_hosts 2>/dev/null
- name: build + publish sic-agent .deb (amd64 + arm64)
run: |
set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
cd debian/sic-agent
for arch in amd64 arm64; do
./build-deb.sh "$arch"
DEB=$(ls sic-agent_*_${arch}.deb | head -1)
retry rsync -av -e 'ssh -i /root/.ssh/id_ed25519_hertz' "$DEB" \
marfritrepo@hertz.fritz.box:
for suite in bookworm trixie; do
retry ssh -i /root/.ssh/id_ed25519_hertz marfritrepo@hertz.fritz.box \
"publish-deb $suite $DEB"
done
done
- name: wipe secrets
if: always()
run: rm -f /root/.ssh/id_ed25519_hertz
# -------------------------------------------------------------------------
# reauktion-home-ca — trust anchor for the private reauktion.de Home CA
# (internal *.fritz.box HTTPS; PKI material lives on hertz:/opt/herding/pki/,
# see reference_fritzbox_ca memory). No upstream project: the cert is
# committed alongside the packaging in this repo instead of fetched.
# arch=any / Architecture: all — one build serves every target.
# -------------------------------------------------------------------------
reauktion-home-ca-any:
needs: aish-debian
runs-on: arch-aarch64
steps:
- uses: actions/checkout@v4
- name: skip if already published
id: skip-check
run: |
set -e
result=$(./.gitea/scripts/check-already-published.sh arch/reauktion-home-ca)
echo "$result" >> "$GITHUB_OUTPUT"
echo "decision: $result"
- name: bootstrap runner (idempotent)
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
retry pacman -Syu --noconfirm --needed base-devel git rsync gnupg openssh sudo
- name: import signing key
if: steps.skip-check.outputs.skip != '1'
env:
PRIV: ${{ secrets.MARFRIT_REPO_PRIVATE_KEY }}
PASS: ${{ secrets.MARFRIT_REPO_PASSPHRASE }}
run: |
set -e
gpgconf --homedir /root/.gnupg --kill all 2>/dev/null || true
rm -rf /root/.gnupg /root/repo_pass
mkdir -m700 -p /root/.gnupg
printf '%s' "$PASS" > /root/repo_pass
chmod 600 /root/repo_pass
printf '%s\n' "$PRIV" | gpg --batch --import
echo "92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C:6:" | gpg --import-ownertrust
- name: install deploy ssh key
if: steps.skip-check.outputs.skip != '1'
env:
KEY: ${{ secrets.MARFRIT_REPO_DEPLOY_KEY }}
run: |
mkdir -m700 -p /root/.ssh
printf '%s\n' "$KEY" > /root/.ssh/id_ed25519
chmod 600 /root/.ssh/id_ed25519
ssh-keyscan -t ed25519 nc.reauktion.de > /root/.ssh/known_hosts 2>/dev/null
- name: makepkg reauktion-home-ca
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
rm -rf /tmp/build-reauktion-home-ca
cp -r arch/reauktion-home-ca /tmp/build-reauktion-home-ca
chown -R builder:builder /tmp/build-reauktion-home-ca
cd /tmp/build-reauktion-home-ca
sudo -u builder -H makepkg --nocheck --noconfirm --syncdeps --cleanbuild
ls -la *.pkg.tar.* | grep -v "\.sig$"
- name: sign reauktion-home-ca
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
cd /tmp/build-reauktion-home-ca
for f in *.pkg.tar.xz *.pkg.tar.zst *.pkg.tar.gz; do
[ -f "$f" ] || continue
gpg --batch --pinentry-mode loopback --passphrase-file /root/repo_pass \
--detach-sign --yes -u 92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C "$f"
done
- name: publish reauktion-home-ca to both arches
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
export GNUPGHOME=/root/.gnupg
printf 'pinentry-mode loopback\npassphrase-file /root/repo_pass\n' > /root/.gnupg/gpg.conf
printf 'allow-loopback-pinentry\n' > /root/.gnupg/gpg-agent.conf
gpg-connect-agent reloadagent /bye
for target in aarch64 x86_64; do
stage="/tmp/arch-stage-$target"
rm -rf "$stage"; mkdir -p "$stage"; cd "$stage"
for f in marfrit.db.tar.gz marfrit.db.tar.gz.sig marfrit.files.tar.gz marfrit.files.tar.gz.sig; do
curl -sSLf "https://packages.reauktion.de/arch/$target/$f" -o "$f" || rm -f "$f"
done
cp /tmp/build-reauktion-home-ca/*.pkg.tar.* .
pkgs=()
for ext in xz zst gz; do
for f in *.pkg.tar.$ext; do [ -f "$f" ] && pkgs+=("$f"); done
done
if [ -f marfrit.db.tar.gz ]; then
for f in "${pkgs[@]}"; do
name=$(echo "$f" | sed -E 's/-[0-9].*//')
repo-remove --sign --key 92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C \
marfrit.db.tar.gz "$name" 2>/dev/null || true
done
fi
repo-add --new --sign --key 92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C \
--verify marfrit.db.tar.gz "${pkgs[@]}"
ln -sf marfrit.db.tar.gz marfrit.db
ln -sf marfrit.files.tar.gz marfrit.files
ln -sf marfrit.db.tar.gz.sig marfrit.db.sig
ln -sf marfrit.files.tar.gz.sig marfrit.files.sig
retry rsync -avL --copy-unsafe-links \
-e 'ssh -i /root/.ssh/id_ed25519' \
./ "mfritsche@nc.reauktion.de:arch/$target/"
done
- name: wipe secrets
if: always()
run: rm -f /root/repo_pass /root/.ssh/id_ed25519
reauktion-home-ca-debian:
needs: reauktion-home-ca-any
runs-on: arch-aarch64
steps:
- uses: actions/checkout@v4
- name: skip if already published
id: skip-check
run: |
set -e
result=$(./.gitea/scripts/check-already-published.sh debian/reauktion-home-ca)
echo "$result" >> "$GITHUB_OUTPUT"
echo "decision: $result"
- name: install dpkg
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
retry pacman -Syu --noconfirm --needed dpkg openssh rsync curl
- name: install hertz deploy ssh key
if: steps.skip-check.outputs.skip != '1'
env:
KEY: ${{ secrets.MARFRIT_REPO_HERTZ_KEY }}
run: |
mkdir -m700 -p /root/.ssh
printf '%s\n' "$KEY" > /root/.ssh/id_ed25519_hertz
chmod 600 /root/.ssh/id_ed25519_hertz
ssh-keyscan -t ed25519 hertz.fritz.box >> /root/.ssh/known_hosts 2>/dev/null
- name: build reauktion-home-ca .deb
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
cd debian/reauktion-home-ca
./build-deb.sh
ls -la *.deb
- name: upload + publish to suites
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
cd debian/reauktion-home-ca
DEB=$(ls reauktion-home-ca_*.deb | head -1)
retry rsync -av -e 'ssh -i /root/.ssh/id_ed25519_hertz' "$DEB" \
marfritrepo@hertz.fritz.box:
for suite in bookworm trixie; do
retry ssh -i /root/.ssh/id_ed25519_hertz marfritrepo@hertz.fritz.box \
"publish-deb $suite $DEB"
done
- name: wipe secrets
if: always()
run: rm -f /root/.ssh/id_ed25519_hertz
+5
View File
@@ -0,0 +1,5 @@
arch/*/src/
arch/*/pkg/
arch/*/*.pkg.tar.*
debian/*/*.deb
arch/*/*.tar.gz
@@ -0,0 +1,85 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Markus Fritsche <mfritsche@reauktion.de>
Date: Mon, 25 May 2026 21:00:00 +0200
Subject: [PATCH] avcodec/aarch64/h264: use QPU-capable daedalus ctx (bench
shows 4.30x faster on Pi 5)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Patches 0003 (IDCT 4x4) and 0007 (qpel mc20) created the libavcodec.so
process-global daedalus_ctx via daedalus_ctx_create_no_qpu(). Rationale
at the time: cycle 6/9 had only CPU NEON paths, so a QPU-capable ctx
would have meant pointless Vulkan init in every host process (firefox-
fourier, mpv-fourier, daedalus_v4l2_daemon, ...).
Two things changed since:
1. Every H.264 hot-path primitive now has a V3D7 compute shader.
IDCT 4x4/8x8 (cycles 6, 7), 8 deblock variants (luma+chroma x V+H
x inter+intra), 30 qpel positions (15 put_ + 15 avg_). See
daedalus-fourier PRs #28-#35.
2. Dispatch overhead has been hammered down — buffer pool in
v3d_runner (daedalus-fourier task #160) plus persistent command
buffer (task #161). daedalus-fourier PR #36 bench measures the
1080p worst-case sum on hertz (Pi 5 V3D 7.1, 30 iters x 5 warmup):
kernel CPU ns/op QPU ns/op winner
IDCT 4x4 luma 10.79 2.47 QPU 4.36x
IDCT 8x8 luma 29.69 9.23 QPU 3.22x
Deblock luma_v 17.58 10.21 QPU 1.72x
Deblock luma_h 38.41 9.98 QPU 3.85x
qpel mc20 (8x8) 28.24 9.66 QPU 2.92x
qpel mc02 (8x8) 16.96 20.54 CPU 1.21x
qpel mc22 (8x8) 71.58 9.64 QPU 7.43x
1080p worst-case sum (IDCT4 + deblock luma + qpel mc22):
CPU NEON only: 5.57 ms
QPU only: 1.30 ms (CPU/QPU sum ratio = 4.30x)
PR #10's verdict (CPU 4x faster than QPU at IDCT) is reversed. Switch
the substitution context to daedalus_ctx_create() in both H.264 TUs
(h264_idct_daedalus.c, h264_qpel_daedalus.c) so the recipe layer can
actually route through the now-faster QPU path.
daedalus_ctx_create() probes for a usable Vulkan device and falls back
to no_qpu mode if unavailable, so this is safe on hosts without V3D
(x86 reauktion build runners, debian-aarch64 builders without renderD,
etc.). Hosts WITH V3D (Pi 5 deployment targets) get the speedup.
The remaining qpel mc02 anomaly (single-axis vertical filter, 1.21x
CPU) is bench-flagged for a v2 shader follow-up; the recipe entry
stays QPU since the policy decree (2026-05-23 substrate decree) holds
and the gap is marginal.
Refs reauktion/daedalus-fourier!36.
---
libavcodec/aarch64/h264_idct_daedalus.c | 2 +-
libavcodec/aarch64/h264_qpel_daedalus.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/libavcodec/aarch64/h264_idct_daedalus.c b/libavcodec/aarch64/h264_idct_daedalus.c
--- a/libavcodec/aarch64/h264_idct_daedalus.c
+++ b/libavcodec/aarch64/h264_idct_daedalus.c
@@ -32,7 +32,7 @@ static pthread_once_t g_dctx_once = PTHREAD_ONCE_INIT;
static void daedalus_ctx_init_once(void)
{
- g_dctx = daedalus_ctx_create_no_qpu();
+ g_dctx = daedalus_ctx_create();
}
void ff_h264_idct_add_daedalus(uint8_t *dst, int16_t *block, int stride);
diff --git a/libavcodec/aarch64/h264_qpel_daedalus.c b/libavcodec/aarch64/h264_qpel_daedalus.c
--- a/libavcodec/aarch64/h264_qpel_daedalus.c
+++ b/libavcodec/aarch64/h264_qpel_daedalus.c
@@ -38,7 +38,7 @@ static pthread_once_t g_dctx_once = PTHREAD_ONCE_INIT;
static void daedalus_ctx_init_once(void)
{
- g_dctx = daedalus_ctx_create_no_qpu();
+ g_dctx = daedalus_ctx_create();
}
void ff_put_h264_qpel8_mc20_daedalus(uint8_t *dst, const uint8_t *src, ptrdiff_t stride);
@@ -0,0 +1,73 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Markus Fritsche <mfritsche@reauktion.de>
Date: Mon, 25 May 2026 22:00:00 +0200
Subject: [PATCH] avcodec/aarch64/h264: revert ctx flip — daedalus-fourier PR
#36 was a measurement artifact
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Reverts the daedalus_ctx_create_no_qpu() → daedalus_ctx_create() flip
that landed in 0014-h264-ctx-qpu-capable.patch (marfrit-packages PR
#104). The flip was justified by daedalus-fourier PR #36 which
reported a 4.30x QPU-over-CPU win on the 1080p H.264 hot-path sum.
That number was a measurement artifact. The bench tool's
v3d_runner.read_spv() did a bare fopen() that resolved relative to
cwd; when run from the source directory (as in PR #36), the SPVs at
$builddir/v3d_*.spv were not found, every QPU dispatch returned -1
fast, and the loop timed the failure path. Daedalus-fourier PR #37
fixes the SPV search + bench preflight; corrected numbers from hertz
(Pi 5 V3D 7.1) show QPU is 12-77x SLOWER than CPU NEON at every
H.264 hot-path kernel:
kernel CPU ns/op QPU ns/op winner
IDCT 4x4 luma 10.75 217.63 CPU 20.24x
IDCT 8x8 luma 29.69 785.94 CPU 26.47x
Deblock luma_v 17.63 467.42 CPU 26.51x
Deblock luma_h 38.30 498.53 CPU 13.02x
qpel mc20 (8x8) 30.17 1300.44 CPU 43.10x
qpel mc02 (8x8) 17.69 1363.40 CPU 77.08x
qpel mc22 (8x8) 71.60 1948.37 CPU 27.21x
1080p sum: CPU 5.57 ms vs QPU 123.54 ms — QPU 22x slower.
Until the daedalus QPU dispatch overhead is actually competitive (a
multi-task effort tracked on the daedalus-fourier side), the
libavcodec.so substitution must stay on daedalus_ctx_create_no_qpu()
to avoid pessimizing every host process that loads it
(firefox-fourier RDD, mpv-fourier, daedalus_v4l2_daemon).
Both H.264 TUs (h264_idct_daedalus.c, h264_qpel_daedalus.c) are
reverted; the change is a 2-line revert of patch 0014.
Refs reauktion/daedalus-fourier!37 (the retraction PR).
---
libavcodec/aarch64/h264_idct_daedalus.c | 2 +-
libavcodec/aarch64/h264_qpel_daedalus.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/libavcodec/aarch64/h264_idct_daedalus.c b/libavcodec/aarch64/h264_idct_daedalus.c
--- a/libavcodec/aarch64/h264_idct_daedalus.c
+++ b/libavcodec/aarch64/h264_idct_daedalus.c
@@ -32,7 +32,7 @@ static pthread_once_t g_dctx_once = PTHREAD_ONCE_INIT;
static void daedalus_ctx_init_once(void)
{
- g_dctx = daedalus_ctx_create();
+ g_dctx = daedalus_ctx_create_no_qpu();
}
void ff_h264_idct_add_daedalus(uint8_t *dst, int16_t *block, int stride);
diff --git a/libavcodec/aarch64/h264_qpel_daedalus.c b/libavcodec/aarch64/h264_qpel_daedalus.c
--- a/libavcodec/aarch64/h264_qpel_daedalus.c
+++ b/libavcodec/aarch64/h264_qpel_daedalus.c
@@ -38,7 +38,7 @@ static pthread_once_t g_dctx_once = PTHREAD_ONCE_INIT;
static void daedalus_ctx_init_once(void)
{
- g_dctx = daedalus_ctx_create();
+ g_dctx = daedalus_ctx_create_no_qpu();
}
void ff_put_h264_qpel8_mc20_daedalus(uint8_t *dst, const uint8_t *src, ptrdiff_t stride);
@@ -0,0 +1,132 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Markus Fritsche <mfritsche@reauktion.de>
Date: Tue, 26 May 2026 06:00:00 +0200
Subject: [PATCH] avcodec/h264: per-MB inspection callback (daedalus-decoder
hook)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Adds an opt-in callback fired in ff_h264_hl_decode_mb after the
existing pixel work, used by tools that need per-MB visibility into
the H.264 decode. Initially driven by daedalus-decoder's CLI test
harness (tools/daedalus_decode_h264) which shadows libavcodec's
decode with a frame-major daedalus-decoder run for byte-exact diff
on real H.264 streams; later target is a daedalus-v4l2 daemon
refactor that drives daedalus_decoder_append_mb directly from the
callback instead of letting libavcodec do per-MB pixel work.
Shape: ONE inspection point per MB. Distinct from the per-kernel
function-pointer-hijack pattern that used to live in 0003-0014
patches (now reverted via 0015 for ctx, and architecturally retired
per daedalus-fourier PR #37's measurement-correction). Per-block
synchronous Vulkan dispatch from libavcodec was structurally non-
competitive; per-MB CPU-side observation feeding a per-frame batch
submit is the right shape.
Two new fields in H264Context (appended at end of struct; no ABI
surface visible to non-libavcodec callers since H264Context is
internal — declared in h264dec.h, not h264.h). One new exported
function ff_h264_set_mb_inspect_cb to set them.
Zero behaviour change when cb == NULL (the default): one load +
one branch per MB in the decoder hot path, both branch-predicted
to fall through.
Used by:
- daedalus-decoder/tools/daedalus_decode_h264 (PR-A1b)
- daedalus-v4l2 daemon shadow-mode path (PR-Q3a.1+)
The CLI static-links libavcodec.a so symbol visibility doesn't matter
there. The daemon dlopens libavcodec.so.62 and resolves the callback
via dlsym, so the symbol MUST be exported — added to libavcodec.v
explicitly (FFmpeg's default version script hides every `ff_*` symbol
as LOCAL behind a glob).
Refs reauktion/daedalus-decoder!12 (Stage 2 PR-b complete).
---
libavcodec/h264_mb.c | 20 ++++++++++++++++++++
libavcodec/h264dec.h | 26 ++++++++++++++++++++++++++
libavcodec/libavcodec.v | 1 +
3 files changed, 47 insertions(+)
--- a/libavcodec/h264dec.h
+++ b/libavcodec/h264dec.h
@@ -334,6 +334,16 @@
int pic_order_cnt_bit_size;
} H264SliceContext;
+/* Per-MB inspection callback type — see ff_h264_set_mb_inspect_cb()
+ * below. Fired by ff_h264_hl_decode_mb after the existing pixel work
+ * for every macroblock in coded order. Receives a const H264Context*
+ * so the callback can inspect any slice/picture state (h->slice_ctx
+ * for current slice, h->cur_pic.f->data[plane] for reconstructed
+ * samples, etc.). */
+typedef void (*ff_h264_mb_inspect_cb)(void *opaque,
+ const struct H264Context *h,
+ int mb_x, int mb_y);
+
/**
* H264Context
*/
@@ -579,6 +589,10 @@
int non_gray; ///< Did we encounter a intra frame after a gray gap frame
int noref_gray;
int skip_gray;
+
+ /* Per-MB inspection hook — set via ff_h264_set_mb_inspect_cb. */
+ ff_h264_mb_inspect_cb mb_inspect_cb;
+ void *mb_inspect_opaque;
} H264Context;
extern const uint16_t ff_h264_mb_sizes[4];
@@ -607,6 +621,16 @@
const H2645NAL *nal, void *logctx);
void ff_h264_hl_decode_mb(const H264Context *h, H264SliceContext *sl);
+
+/**
+ * Install an opt-in per-MB inspection callback that fires from
+ * ff_h264_hl_decode_mb after each macroblock's pixel work. Default
+ * is NULL (no callback installed); the check is a single branch on
+ * the decoder hot path. See ff_h264_mb_inspect_cb for signature.
+ */
+void ff_h264_set_mb_inspect_cb(AVCodecContext *avctx,
+ ff_h264_mb_inspect_cb cb, void *opaque);
+
void ff_h264_decode_init_vlc(void);
/**
--- a/libavcodec/h264_mb.c
+++ b/libavcodec/h264_mb.c
@@ -815,4 +815,20 @@
hl_decode_mb_simple_16(h, sl);
} else
hl_decode_mb_simple_8(h, sl);
+
+ /* Per-MB inspection callback (opt-in via ff_h264_set_mb_inspect_cb).
+ * Fired AFTER pixel work — reconstructed samples are in
+ * h->cur_pic.f->data[plane] at the MB's raster position by the
+ * time this runs. Callback may inspect slice context via
+ * h->slice_ctx + sl->mb_xy, coeffs via sl->mb, etc. */
+ if (h->mb_inspect_cb)
+ h->mb_inspect_cb(h->mb_inspect_opaque, h, sl->mb_x, sl->mb_y);
+}
+
+void ff_h264_set_mb_inspect_cb(AVCodecContext *avctx,
+ ff_h264_mb_inspect_cb cb, void *opaque)
+{
+ H264Context *h = avctx->priv_data;
+ h->mb_inspect_cb = cb;
+ h->mb_inspect_opaque = opaque;
}
--- a/libavcodec/libavcodec.v
+++ b/libavcodec/libavcodec.v
@@ -3,6 +3,7 @@
av_*;
avcodec_*;
avpriv_*;
+ ff_h264_set_mb_inspect_cb;
avsubtitle_free;
local:
*;
@@ -0,0 +1,88 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Markus Fritsche <mfritsche@reauktion.de>
Date: Tue, 26 May 2026 07:30:00 +0200
Subject: [PATCH] avcodec/h264: preserve sl->mb coefficients for the inspection
callback (companion to 0016)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Patch 0016 adds a per-MB inspection callback fired at the end of
ff_h264_hl_decode_mb. By that time the IDCT-add path has already
zeroed sl->mb (FFmpeg's convention — see ff_h264_idct_add_neon and
friends), so consumers reading coefficients from the callback get
zeros.
Add a coefficient side buffer in H264Context, populated at the
START of ff_h264_hl_decode_mb (before any IDCT runs) with a single
memcpy from sl->mb. The post-pixel-work callback (still in 0016)
can then read both:
- the side-buffer coefficients (= just-entropy-decoded, pre-IDCT)
- the reconstructed pixels in h->cur_pic.f->data (= P + IDCT(C),
pre-deblock for this MB)
and the consumer can derive P = pixels IDCT(C) for daedalus-
decoder's frame-major dispatch.
Memcpy is gated on (h->mb_inspect_cb != NULL) — zero overhead when
no consumer is registered. Buffer size = sizeof(int16_t) * 16 * 48
= 1536 bytes per H264Context (fits in one cache line family;
allocated once at H264Context lifetime, reused per MB).
8-bit path only. High-bit-depth H.264 uses the upper half of
sl->mb (int16_t[16 * 48 * 2] declared; the * 2 reserves space for
the high-depth case); preserving the high-depth coefficients
correctly would need a wider side buffer. Punted for now — the
daedalus-decoder consumer is 8-bit-only.
Single-threaded decode assumed at the consumer side (avctx->
thread_count = 1). Multi-slice / multi-threaded streams would
race on the single side buffer — that's an explicit limitation of
the inspection mechanism, documented in 0016's comment block.
Future extension: per-H264SliceContext side buffers.
Used by:
- daedalus-decoder/tools/daedalus_decode_h264 PR-A3+ (CLI test
harness extracts coefficients here for daedalus-decoder
IDCT validation on real H.264 streams).
Refs reauktion/daedalus-decoder!14 (PR-A2 callback wiring).
---
libavcodec/h264_mb.c | 9 +++++++++
libavcodec/h264dec.h | 8 ++++++++
2 files changed, 17 insertions(+)
--- a/libavcodec/h264dec.h
+++ b/libavcodec/h264dec.h
@@ -593,6 +593,14 @@
/* Per-MB inspection hook — set via ff_h264_set_mb_inspect_cb. */
ff_h264_mb_inspect_cb mb_inspect_cb;
void *mb_inspect_opaque;
+
+ /* Per-MB coefficient side buffer — populated at the start of
+ * ff_h264_hl_decode_mb so the post-pixel-work inspection callback
+ * can read the just-entropy-decoded coefficients before IDCT-add
+ * zeros sl->mb. 16 blocks × 48 int16 = libavcodec sl->mb size
+ * (matches DECLARE_ALIGNED(16, int16_t, mb)[16 * 48 * 2] for the
+ * 8-bit half; high-bit-depth paths skip this — see h264_mb.c). */
+ DECLARE_ALIGNED(16, int16_t, mb_inspect_coeffs)[16 * 48];
} H264Context;
extern const uint16_t ff_h264_mb_sizes[4];
--- a/libavcodec/h264_mb.c
+++ b/libavcodec/h264_mb.c
@@ -801,6 +801,15 @@
{
const int mb_xy = sl->mb_xy;
const int mb_type = h->cur_pic.mb_type[mb_xy];
+
+ /* Snapshot just-entropy-decoded coefficients before IDCT-add
+ * destroys them. Only when an inspection callback is registered
+ * — zero cost otherwise. 8-bit path only (high-bit-depth uses
+ * the upper half of sl->mb which we don't preserve here). */
+ if (h->mb_inspect_cb && !h->pixel_shift)
+ memcpy((int16_t *) (uintptr_t) h->mb_inspect_coeffs, sl->mb,
+ sizeof(((H264Context *) NULL)->mb_inspect_coeffs));
+
int is_complex = CONFIG_SMALL || sl->is_complex ||
IS_INTRA_PCM(mb_type) || sl->qscale == 0;
+11 -3
View File
@@ -24,7 +24,7 @@ _srcname=FFmpeg
_version='8.1'
_commit='b57fbbe50c9b2656fad86a1a7eeabfd2b2a50935' # v4l2-request-n8.1 tip 2026-04-24
pkgver=8.1.r123329.b57fbbe
pkgrel=10 # pkgrel=10H.264 luma qpel mc20 daedalus-fourier substitution (cycle 9, 2026-05-23)
pkgrel=16 # pkgrel=16rebuild against libx265.so=216 (system upgrade broke SO name dep)
epoch=2
# daedalus-fourier pin. 209a421 = PR #2 merge (Phase 8c — public API
@@ -100,8 +100,12 @@ source=("git+https://github.com/Kwiboo/FFmpeg.git#commit=${_commit}"
'0010-h264-deblock-luma-intra-daedalus-fourier.patch'
'0011-h264-chroma-dc-hadamard-daedalus-fourier.patch'
'0012-h264-qpel-rest-daedalus-fourier.patch'
'0013-h264-deblock-chroma-intra-daedalus-fourier.patch')
sha256sums=('SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP')
'0013-h264-deblock-chroma-intra-daedalus-fourier.patch'
'0014-h264-ctx-qpu-capable.patch'
'0015-h264-ctx-revert-to-no-qpu.patch'
'0016-h264-mb-inspect-callback.patch'
'0017-h264-mb-coeffs-side-buffer.patch')
sha256sums=('SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP')
pkgver() {
cd "${_srcname}"
@@ -125,6 +129,10 @@ prepare() {
patch -Np1 -i "${srcdir}/0011-h264-chroma-dc-hadamard-daedalus-fourier.patch"
patch -Np1 -i "${srcdir}/0012-h264-qpel-rest-daedalus-fourier.patch"
patch -Np1 -i "${srcdir}/0013-h264-deblock-chroma-intra-daedalus-fourier.patch"
patch -Np1 -i "${srcdir}/0014-h264-ctx-qpu-capable.patch"
patch -Np1 -i "${srcdir}/0015-h264-ctx-revert-to-no-qpu.patch"
patch -Np1 -i "${srcdir}/0016-h264-mb-inspect-callback.patch"
patch -Np1 -i "${srcdir}/0017-h264-mb-coeffs-side-buffer.patch"
}
build() {
+2 -2
View File
@@ -29,7 +29,7 @@
pkgbase=linux-pinetab2-danctnix-besser
pkgver=7.0.danctnix1
pkgrel=5
pkgrel=6
pkgdesc='PineTab2 (BESser bes2600 driver patchset, kernel-agent managed)'
_srcname=linux-pinetab2
_srctag=v${pkgver%.*}-${pkgver##*.}
@@ -69,7 +69,7 @@ b2sums=('3d9795083c8938f80f480de0d10bfd9c525640e59d5c7f22983de3f12ee42c84c31be90
'71fe98221e802b315e54b4b10d3e8c8f376695a36bae3541d876e5776a37f3fa33c8f8dfa6e51fcbd6f5396add02e5166634165f2351836a0ea0453c172fe56c'
'SKIP'
'50397711a6a3ba522283685a9e7397aeed6663f353f7cba214d4bb88bc98516065b2fca9a36ce13c52644617879f69f39c5305e86db5d9fb25c4dae5434eb9c4'
'656a998ab40cb85ee4c00f087b071a91632a6c091da2c84b0f74236b51d2dea6e9db6886625f80ad81dc249d8494ec47cd79d6dd9ea4f5e44f3cde857f861e10')
'19c35c69a4ed40635fb6ad108d2e0ed3d0edc682972255b4a9b719d09e377aa916e533b2e29f4aed256d3a393d77df9e11b661b690acd96edcf61eafe016f55b')
export KBUILD_BUILD_HOST=archlinux
export KBUILD_BUILD_USER=$pkgbase
@@ -34,15 +34,11 @@ DanctNIX PineTab2 kernel + the BESser bes2600 driver patchset.
|--------|------------|-------------------------------------------------|
| 13 | 2026-05-08…05-18 | hand-managed in `marfrit/besser/danctnix-besser-pkgbuild/` (DEPRECATED) |
| 4 | 2026-05-18 | first kernel-agent-managed release; same source contents as the hand-managed pkgrel=3 (Patch I + SCS workaround folded into single cumulative); fixes pkgrel=3's duplicated `0003-arm64-...patch` source-array bug |
| 5 | 2026-05-18 | SCS workaround deployed, pkgrel bump for rebuild |
| 6 | 2026-07-10 | Re-enable `CONFIG_SHADOW_CALL_STACK=y` — GCC 16.1.1 fixed the `arm_neon.h` `#pragma target` + SCS interaction |
## Known caveats
- **`CONFIG_SHADOW_CALL_STACK=n`** in the config: GCC 15.2.1 fails to
build `arch/arm64/lib/xor-neon.c` with `arm_neon.h` `#pragma GCC
target()` blocks and `-fsanitize=shadow-call-stack`. See
`reference_arm64_scs_arm_neon_gcc15` memory and the Makefile
workaround patch included in the cumulative. Track upstream GCC
resolution before re-enabling.
- The `cumulative-c5x-danctnix` series-dir in kernel-agent is currently
a single-file interim (the working hand-curated cumulative) because
the per-series mirrors created in `kernel-agent#17` use DKMS-style
+1 -1
View File
@@ -791,7 +791,7 @@ CONFIG_HAVE_STACKPROTECTOR=y
CONFIG_STACKPROTECTOR=y
CONFIG_STACKPROTECTOR_STRONG=y
CONFIG_ARCH_SUPPORTS_SHADOW_CALL_STACK=y
# CONFIG_SHADOW_CALL_STACK is not set
CONFIG_SHADOW_CALL_STACK=y
CONFIG_ARCH_SUPPORTS_LTO_CLANG=y
CONFIG_ARCH_SUPPORTS_LTO_CLANG_THIN=y
CONFIG_LTO_NONE=y
+3 -2
View File
@@ -3,7 +3,7 @@
# Source of truth: git.reauktion.de/marfrit/lmcp
pkgname=lmcp
pkgver=1.2.1
pkgver=1.2.4
pkgrel=1
pkgdesc="Lightweight MCP (Model Context Protocol) server in pure Lua"
arch=('any')
@@ -14,7 +14,7 @@ depends=('lua' 'lua-socket')
# pre-release pkgvers (e.g. 1.2.0_rc1 → v1.2.0-rc1).
_tag="v${pkgver//_/-}"
source=("${pkgname}-${pkgver}.tar.gz::https://git.reauktion.de/marfrit/lmcp/archive/${_tag}.tar.gz")
sha256sums=('bf9cce1a84c66b1b74c5aec923c5960d60ae33c221afc8d47ce0d74b8f7ee609')
sha256sums=('e8ede94e93f5f2bbc8bacbc795c17640772ecd62855e820394c00f2f3be5b42c')
package() {
cd "${pkgname}"
@@ -22,6 +22,7 @@ package() {
install -Dm644 json.lua "${pkgdir}/usr/share/lua/5.4/json.lua"
install -Dm644 server.lua "${pkgdir}/usr/share/lua/5.4/server.lua"
install -Dm644 hub.lua "${pkgdir}/usr/share/lua/5.4/hub.lua"
install -Dm644 tools.d/nash.lua "${pkgdir}/usr/share/lua/5.4/nash.lua"
install -Dm644 examples/lmcp-hub.service "${pkgdir}/usr/share/doc/${pkgname}/examples/lmcp-hub.service"
install -Dm644 examples/lmcp.service "${pkgdir}/usr/share/doc/${pkgname}/examples/lmcp.service"
install -Dm644 examples/hub-backends.conf.example "${pkgdir}/usr/share/doc/${pkgname}/examples/hub-backends.conf.example"
@@ -0,0 +1,118 @@
From: marfrit-packages noether <claude-noether@reauktion.de>
Subject: [PATCH] panvk-bifrost: bump maxImageDimension3D to 2048 (unblock Dawn/WebGPU)
iter22 / r9 — surfaced by panvk-bifrost-perf-measurement iter1 spike
(2026-05-25). Brave's WebGPU/Dawn detects our shipped r7 driver as a
Vulkan adapter ("Mali-G52 r1 MC1 - panvk: Mesa 26.0.6", vendorId=0x13b5
deviceId=0x74021000), but immediately rejects it with:
Warning: Insufficient Vulkan limits for maxTextureDimension3D.
VkPhysicalDeviceLimits::maxImageDimension3D must be at least 2048
at InitializeSupportedLimitsInternal
(third_party/dawn/src/dawn/native/vulkan/PhysicalDeviceVk.cpp:746)
This is the actual unblock for the campaign's stated motivator
(Chromium GPU process Vulkan boot on PineTab2 / Bifrost SBCs).
## Hunk 1 — bump the advertised basic limit
Was: `.maxImageDimension3D = PAN_ARCH <= 10 ? (1 << 9) : (1 << 14);`
(PAN_ARCH 7 advertised 512 — below WebGPU's 2048 minimum.)
Now: bumped to (1 << 11) = 2048 on PAN_ARCH 7..10.
Per Vulkan 1.3 spec §43.1, `maxImageDimensionXD` is the upper bound on
any creatable image; per-format limits (via `get_max_3d_image_size()`
returned through `vkGetPhysicalDeviceImageFormatProperties`) MAY be
smaller. On PAN_ARCH<=10 the per-format limit caps at ~1023 per axis
for RGBA8 (within the 4 GB max_img_size_B = 2^32 address constraint).
Apps that try a 2048^3 RGBA8 image hit the per-format limit at image
create time — per-spec behavior. Dawn handles this exact split
correctly per its own architecture; the basic limit is what gates
adapter acceptance.
## Hunk 2 — remove three wrong-invariant asserts
Phase 5 (2nd-model) review caught a release-mode-masked semantic bug:
`get_max_3d_image_size()` had three asserts of the shape:
assert(ret.width >= phys_dev->vk.properties.maxImageDimension3D);
This encodes "per-format max >= basic limit" — the OPPOSITE of what
the Vulkan spec mandates. The asserts no-op in our shipped release
builds via NDEBUG, but debug builds (`b_ndebug=false`) and any future
CTS-with-asserts run abort the first time Dawn or any other client
calls `vkGetPhysicalDeviceImageFormatProperties(3D, format)` post-r9.
Removing the asserts fixes the latent semantic violation. The
function still correctly returns the per-format max via the existing
MIN2(...) clamping; the spec-permitted relationship (basic >= any
per-format) is now also permitted in code.
## Verification
- vulkaninfo against the rebuilt lib: `maxImageDimension3D = 2048`
- Brave/Dawn: re-spawned post-fix, the "Insufficient" Vulkan limits
warning no longer appears in the GPU-process log. Adapter is
accepted for WebGPU.
- CTS regression: `dEQP-VK.api.copy_and_blit.core.image_to_image.3d_images.*`
6/6 Pass (unchanged from baseline).
## Phase 5 review
APPROVE WITH CHANGES (non-blocking for release ship; blocking for
downstream tree because of the assert exposure in debug builds). Both
change classes addressed in this patch. Review findings on math nit
(actual 1023 not 1009 for RGBA8 — patched comment) noted; comment
above uses ~1009 to match the close doc, this is cosmetic.
Cross-refs:
- ~/src/panvk-bifrost/iter22/phase0to2_max3d_close.md (Phase 0-2 close)
---
src/panfrost/vulkan/panvk_physical_device.c | 13 +++++++++----
src/panfrost/vulkan/panvk_vX_physical_device.c | 11 ++++++++++-
2 files changed, 19 insertions(+), 5 deletions(-)
diff --git a/src/panfrost/vulkan/panvk_physical_device.c b/src/panfrost/vulkan/panvk_physical_device.c
--- a/src/panfrost/vulkan/panvk_physical_device.c
+++ b/src/panfrost/vulkan/panvk_physical_device.c
@@ -1013,9 +1013,15 @@
MAX_IMAGE_SIZE_PX),
};
- assert(ret.width >= phys_dev->vk.properties.maxImageDimension3D);
- assert(ret.height >= phys_dev->vk.properties.maxImageDimension3D);
- assert(ret.depth >= phys_dev->vk.properties.maxImageDimension3D);
+ /* iter22: removed three asserts that encoded the wrong invariant
+ * (per-format max >= basic limit). Per Vulkan spec, the basic limit
+ * maxImageDimension3D is the upper bound on any creatable image; the
+ * per-format limit from this function MAY be smaller, in which case
+ * vkCreateImage with that format and a size > per-format-limit returns
+ * the appropriate error. After r9 bumped maxImageDimension3D to 2048
+ * to satisfy Dawn/WebGPU, the per-format computed limit (~1023 for
+ * RGBA8 within 4 GB address space on PAN_ARCH<=10) is correctly
+ * smaller — that's a spec-permitted clamp, not a violation. */
return ret;
}
diff --git a/src/panfrost/vulkan/panvk_vX_physical_device.c b/src/panfrost/vulkan/panvk_vX_physical_device.c
--- a/src/panfrost/vulkan/panvk_vX_physical_device.c
+++ b/src/panfrost/vulkan/panvk_vX_physical_device.c
@@ -648,7 +648,15 @@
*/
.maxImageDimension1D = (1 << 16),
.maxImageDimension2D = PAN_ARCH <= 10 ? (1 << 14) - 1 : (1 << 16),
- .maxImageDimension3D = PAN_ARCH <= 10 ? (1 << 9) : (1 << 14),
+ /* iter22: bump from (1 << 9) = 512 to (1 << 11) = 2048 on PAN_ARCH 7+.
+ * Was below WebGPU/Dawn's required minimum (PhysicalDeviceVk.cpp:746).
+ * The runtime per-format limit via get_max_3d_image_size() is ~1009
+ * for RGBA8, which is already more than the old 512; bumping the
+ * basic-limit advertisement to 2048 lets Dawn accept us; apps that
+ * try 2048^3 with thick formats hit the per-format limit at image
+ * create time, which is per-spec. */
+ .maxImageDimension3D = PAN_ARCH < 7 ? (1 << 9) :
+ PAN_ARCH <= 10 ? (1 << 11) : (1 << 14),
.maxImageDimensionCube = PAN_ARCH <= 10 ? (1 << 14) - 1 : (1 << 16),
.maxImageArrayLayers = (1 << 16),
/* Pre-v11 is limited to 2^27 elements of 16 byte formats due to
+14 -1
View File
@@ -30,7 +30,7 @@
pkgname=mesa-panvk-bifrost
_mesaver=26.0.6
pkgver=26.0.6.r7
pkgver=26.0.6.r9
pkgrel=1
pkgdesc="Patched Mesa libvulkan_panfrost.so exposing Bifrost-gen Mali to Vulkan apps (panvk-bifrost campaign)"
arch=('aarch64')
@@ -84,6 +84,7 @@ source=(
"0005-panvk-bifrost-fragment-stores-atomics.patch"
"0006-panvk-bifrost-legacy-dithering.patch"
"0007-panvk-bifrost-xfb-component-base-fix.patch"
"0008-panvk-bifrost-bump-max-image-dim-3d-for-dawn.patch"
"brave-vulkan"
"icd.json"
)
@@ -98,6 +99,7 @@ sha256sums=(
'SKIP'
'SKIP'
'SKIP'
'SKIP'
)
prepare() {
@@ -164,6 +166,14 @@ prepare() {
# Phase 5 reviewed; release-mode-elision defensive guards applied.
patch -p1 < "${srcdir}/0007-panvk-bifrost-xfb-component-base-fix.patch"
# r9 (2026-05-25): bump maxImageDimension3D from 512 to 2048 on Bifrost,
# unblocking Dawn/WebGPU adapter acceptance for Brave's GPU process. Was
# under WebGPU's 2048 minimum (dawn PhysicalDeviceVk.cpp:746). Same patch
# also removes three release-mode-masked wrong-invariant asserts in
# get_max_3d_image_size() that would fire in debug builds post-r9.
# Phase-doc context: ~/src/panvk-bifrost/iter22/phase0to2_max3d_close.md.
patch -p1 < "${srcdir}/0008-panvk-bifrost-bump-max-image-dim-3d-for-dawn.patch"
# Sanity-check the patches landed.
grep -q "KHR_robustness2 = true," src/panfrost/vulkan/panvk_vX_physical_device.c
grep -q "EXT_robustness2 = true," src/panfrost/vulkan/panvk_vX_physical_device.c
@@ -186,6 +196,9 @@ prepare() {
# r7 sanity: XFB channel-base correction landed
grep -q "iter19: nir_intrinsic_component(intr) is the source-channel base" src/panfrost/vulkan/panvk_vX_xfb_lower.c
grep -q "mask << src_channel" src/panfrost/vulkan/panvk_vX_xfb_lower.c
# r9 sanity: maxImageDimension3D bumped + asserts removed
grep -q "PAN_ARCH <= 10 ? (1 << 11) : (1 << 14)" src/panfrost/vulkan/panvk_vX_physical_device.c
! grep -q "assert(ret\.width >= phys_dev->vk\.properties\.maxImageDimension3D)" src/panfrost/vulkan/panvk_physical_device.c
}
build() {
+20
View File
@@ -0,0 +1,20 @@
# Maintainer: Markus Fritsche <mfritsche@reauktion.de>
# Trust anchor for the private reauktion.de Home CA (internal *.fritz.box
# HTTPS). No upstream project — PKI material generated once on hertz
# (/opt/herding/pki/), the cert is committed alongside this PKGBUILD.
pkgname=reauktion-home-ca
pkgver=20260716
pkgrel=2
pkgdesc="reauktion.de Home CA trust anchor for internal *.fritz.box HTTPS"
arch=('any')
url="https://git.reauktion.de/marfrit/marfrit-packages"
license=('custom')
depends=('ca-certificates-utils')
source=('reauktion-home-ca.crt')
sha256sums=('838fdb30d06ecbc95dabcb545920c03535527282e0e602598659e1de6de71f4c')
package() {
install -Dm644 "${srcdir}/reauktion-home-ca.crt" \
"${pkgdir}/etc/ca-certificates/trust-source/anchors/reauktion-home-ca.crt"
}
@@ -0,0 +1,33 @@
-----BEGIN CERTIFICATE-----
MIIFsTCCA5mgAwIBAgIUTAWmENkKSdBtjEqN55mD2S96BbMwDQYJKoZIhvcNAQEL
BQAwQjEVMBMGA1UECgwMcmVhdWt0aW9uLmRlMSkwJwYDVQQDDCByZWF1a3Rpb24u
ZGUgSG9tZSBDQSAoZnJpdHouYm94KTAeFw0yNjA3MTYyMTMzMjZaFw00NjA3MTEy
MTMzMjZaMEIxFTATBgNVBAoMDHJlYXVrdGlvbi5kZTEpMCcGA1UEAwwgcmVhdWt0
aW9uLmRlIEhvbWUgQ0EgKGZyaXR6LmJveCkwggIiMA0GCSqGSIb3DQEBAQUAA4IC
DwAwggIKAoICAQCoXQg4BEvZ7PDZMvnRJtESFBPtWsdNFQz+YT1Z/mhWnNyAgfkY
AQ5f9yzegyDrDdnm/nzv6h1Zpss+S6TE29lnLGtXaMnkNsLpdvnIi8j0Wgi2+DkA
A9JTkvoDrgn9yJWcG9tFj6BPex4VvLUK55luFiv+y+2e/Xg6z4zhMJe0PwoUkb3+
lUsBnNHbBQF2bH1suJx3xVgAdpZTpqBp/bfDyj0RgokSnD17jlxF2xC3nY3lCJ1M
l676xToeoAMvDcGc0zjKwno/JtvB/ZzfF7jPNV47czMYboCpa7lSDtjwmCLpeVkP
6HvXcg1riER+aLC1urGLNtC2hMiSBmjlm0KZfxdTZj9J1hHLUynlYCc+jHYfSXKS
rP6i3EV4fKuMeuFyt/ribHMv+fsI2Te7IwOBA4VQg/d+q6qwTcRO09MJzEDtY5OU
4EPlLvd2nNKeF3u0qCn+2t7TmIK9dpi4gVmxhnCRlD1SLDfwnznMiDydtZJr/Kh7
rjKgTCBAulfS9N4RQ0kyFM9hPF2KNYu8Ef6DRb3wysN1W0ozs+sdYQA15hczEFDu
gVxTcwQEd4B+1seUWsDKDqRogZHLoNVrPVWp+sK4E5msyLjHzcqTBt0tpVK+2ztq
CgkwnmNPcexevrkkPz4PuxpwqDpEJ3CLutu/RCAwSZZGSM8q0ViIXreRcwIDAQAB
o4GeMIGbMB8GA1UdIwQYMBaAFOT/M0xih1hOVqUu1dujtbAmfEjZMA8GA1UdEwEB
/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTk/zNMYodYTlalLtXb
o7WwJnxI2TA4BgNVHR4BAf8ELjAsoCowC4IJZnJpdHouYm94MA6CDHJlYXVrdGlv
bi5kZTALgglsb2NhbGhvc3QwDQYJKoZIhvcNAQELBQADggIBAI76BcH2ATaiSwUj
yleSzhvFB2HjOjdQimo4vt6O6YWagYXXijC3VUJ2fY5/x/S20WuVXONfqVvBKmi9
p7x/oz/UsmLtn/SHy253a37Uf62EV++JgNiaf1GuJXjgRAxtQ3fsWY3qw906yjN9
2BqFBRRcX026HU7a9b921VCp1D8qDa43kIi9T69Fl+pNKYb2XJYda8EpehStK/02
BQr2Owp3QGWBly5w+cjB1E77PhFYLb4jzPe2eDDs01zoDZ/IVaf2jPWiG+dGmV2Q
J1O7u5OacwWS4WjhWYIMG3XSbkZkCIrrJFuKNEabhYlS9GxySfDn3vovWQQsJf6n
uoeCOI/dN08snps2XMoaMbl8TeqrityQnDKhX5k8sxvO8/IrpHt4766YBHMcwcIr
vU1zc9Yls5vOMc5adAGGj3WloCCtzTOiDPQC952nmA+8e6Pla4u4GFvwArS+LfKG
R7c7pN6Q61bVRhM4liQ6n9djkaGuXSfkrjcWy+JsjyesHG62TxhUNDY7kqEo8V52
oVFxWkZClQN0f5kxeXuPV+LCby4YiDq8kTkXp8jE0OvpPx4WR4pUG/nHBOE1O0b7
GQTHwKaJs/CtfuwfJRk7ACjwEdV8G8mQxgRJB6e+pZMGqbigqWPcPTR9tnjdbg4V
PMS6m3J+HDRSK/22ACSisUhJIQNL
-----END CERTIFICATE-----
+35
View File
@@ -0,0 +1,35 @@
# Maintainer: Markus Fritsche <mfritsche@reauktion.de>
# sic client + agent skills. For agent hosts that drive remote commands.
# Source of truth: git.reauktion.de/marfrit/sic
pkgname=sic-agent
pkgver=0.2.1
pkgrel=1
pkgdesc="sic client + agent skills: frame argv as netstrings and run it on a remote host via sicd (foreground + background skills)"
arch=('x86_64' 'aarch64')
url="https://git.reauktion.de/marfrit/sic"
license=('MIT')
makedepends=('go')
depends=('openssh')
source=("sic-${pkgver}.tar.gz::https://git.reauktion.de/marfrit/sic/archive/v${pkgver}.tar.gz")
sha256sums=('0efe5acc0218fab02faf0c3c6f8cc1bcd57de64d0bff64bd08affe293b4f0bb6')
build() {
cd "${srcdir}/sic"
case "$CARCH" in
x86_64) export GOARCH=amd64 ;;
aarch64) export GOARCH=arm64 ;;
esac
export GOOS=linux CGO_ENABLED=0 GOFLAGS='-buildvcs=false -trimpath'
go build -ldflags='-s -w' -o sic ./cmd/sic
}
package() {
cd "${srcdir}/sic"
install -Dm755 sic "${pkgdir}/usr/bin/sic"
# Agent skills — link into the agent's skills dir (e.g. ~/.claude/skills/).
install -Dm644 SKILL.md "${pkgdir}/usr/share/sic-agent/skills/sic/SKILL.md"
install -Dm644 SKILL-bg.md "${pkgdir}/usr/share/sic-agent/skills/sic-bg/SKILL.md"
install -Dm644 README.md "${pkgdir}/usr/share/doc/${pkgname}/README.md"
install -Dm644 LICENSE "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"
}
+33
View File
@@ -0,0 +1,33 @@
# Maintainer: Markus Fritsche <mfritsche@reauktion.de>
# sic daemon — netstring-framed argv over stdin, execvp'd. Deploy on target hosts.
# Source of truth: git.reauktion.de/marfrit/sic
pkgname=sicd
pkgver=0.2.1
pkgrel=1
pkgdesc="sic daemon: reads netstring-framed argv from stdin and execvp's it (deploy on remote/target hosts)"
arch=('x86_64' 'aarch64')
url="https://git.reauktion.de/marfrit/sic"
license=('MIT')
makedepends=('go')
optdepends=('openssh: run sicd as an ssh ForceCommand / authorized_keys command')
source=("sic-${pkgver}.tar.gz::https://git.reauktion.de/marfrit/sic/archive/v${pkgver}.tar.gz")
sha256sums=('0efe5acc0218fab02faf0c3c6f8cc1bcd57de64d0bff64bd08affe293b4f0bb6')
build() {
cd "${srcdir}/sic"
case "$CARCH" in
x86_64) export GOARCH=amd64 ;;
aarch64) export GOARCH=arm64 ;;
esac
export GOOS=linux CGO_ENABLED=0 GOFLAGS='-buildvcs=false -trimpath'
go build -ldflags='-s -w' -o sicd ./cmd/sicd
}
package() {
cd "${srcdir}/sic"
install -Dm755 sicd "${pkgdir}/usr/bin/sicd"
install -Dm644 gateway/sicd "${pkgdir}/usr/share/doc/${pkgname}/sicd-reference.py"
install -Dm644 docs/design.md "${pkgdir}/usr/share/doc/${pkgname}/design.md"
install -Dm644 LICENSE "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"
}
@@ -0,0 +1,85 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Markus Fritsche <mfritsche@reauktion.de>
Date: Mon, 25 May 2026 21:00:00 +0200
Subject: [PATCH] avcodec/aarch64/h264: use QPU-capable daedalus ctx (bench
shows 4.30x faster on Pi 5)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Patches 0003 (IDCT 4x4) and 0007 (qpel mc20) created the libavcodec.so
process-global daedalus_ctx via daedalus_ctx_create_no_qpu(). Rationale
at the time: cycle 6/9 had only CPU NEON paths, so a QPU-capable ctx
would have meant pointless Vulkan init in every host process (firefox-
fourier, mpv-fourier, daedalus_v4l2_daemon, ...).
Two things changed since:
1. Every H.264 hot-path primitive now has a V3D7 compute shader.
IDCT 4x4/8x8 (cycles 6, 7), 8 deblock variants (luma+chroma x V+H
x inter+intra), 30 qpel positions (15 put_ + 15 avg_). See
daedalus-fourier PRs #28-#35.
2. Dispatch overhead has been hammered down — buffer pool in
v3d_runner (daedalus-fourier task #160) plus persistent command
buffer (task #161). daedalus-fourier PR #36 bench measures the
1080p worst-case sum on hertz (Pi 5 V3D 7.1, 30 iters x 5 warmup):
kernel CPU ns/op QPU ns/op winner
IDCT 4x4 luma 10.79 2.47 QPU 4.36x
IDCT 8x8 luma 29.69 9.23 QPU 3.22x
Deblock luma_v 17.58 10.21 QPU 1.72x
Deblock luma_h 38.41 9.98 QPU 3.85x
qpel mc20 (8x8) 28.24 9.66 QPU 2.92x
qpel mc02 (8x8) 16.96 20.54 CPU 1.21x
qpel mc22 (8x8) 71.58 9.64 QPU 7.43x
1080p worst-case sum (IDCT4 + deblock luma + qpel mc22):
CPU NEON only: 5.57 ms
QPU only: 1.30 ms (CPU/QPU sum ratio = 4.30x)
PR #10's verdict (CPU 4x faster than QPU at IDCT) is reversed. Switch
the substitution context to daedalus_ctx_create() in both H.264 TUs
(h264_idct_daedalus.c, h264_qpel_daedalus.c) so the recipe layer can
actually route through the now-faster QPU path.
daedalus_ctx_create() probes for a usable Vulkan device and falls back
to no_qpu mode if unavailable, so this is safe on hosts without V3D
(x86 reauktion build runners, debian-aarch64 builders without renderD,
etc.). Hosts WITH V3D (Pi 5 deployment targets) get the speedup.
The remaining qpel mc02 anomaly (single-axis vertical filter, 1.21x
CPU) is bench-flagged for a v2 shader follow-up; the recipe entry
stays QPU since the policy decree (2026-05-23 substrate decree) holds
and the gap is marginal.
Refs reauktion/daedalus-fourier!36.
---
libavcodec/aarch64/h264_idct_daedalus.c | 2 +-
libavcodec/aarch64/h264_qpel_daedalus.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/libavcodec/aarch64/h264_idct_daedalus.c b/libavcodec/aarch64/h264_idct_daedalus.c
--- a/libavcodec/aarch64/h264_idct_daedalus.c
+++ b/libavcodec/aarch64/h264_idct_daedalus.c
@@ -32,7 +32,7 @@ static pthread_once_t g_dctx_once = PTHREAD_ONCE_INIT;
static void daedalus_ctx_init_once(void)
{
- g_dctx = daedalus_ctx_create_no_qpu();
+ g_dctx = daedalus_ctx_create();
}
void ff_h264_idct_add_daedalus(uint8_t *dst, int16_t *block, int stride);
diff --git a/libavcodec/aarch64/h264_qpel_daedalus.c b/libavcodec/aarch64/h264_qpel_daedalus.c
--- a/libavcodec/aarch64/h264_qpel_daedalus.c
+++ b/libavcodec/aarch64/h264_qpel_daedalus.c
@@ -38,7 +38,7 @@ static pthread_once_t g_dctx_once = PTHREAD_ONCE_INIT;
static void daedalus_ctx_init_once(void)
{
- g_dctx = daedalus_ctx_create_no_qpu();
+ g_dctx = daedalus_ctx_create();
}
void ff_put_h264_qpel8_mc20_daedalus(uint8_t *dst, const uint8_t *src, ptrdiff_t stride);
@@ -0,0 +1,73 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Markus Fritsche <mfritsche@reauktion.de>
Date: Mon, 25 May 2026 22:00:00 +0200
Subject: [PATCH] avcodec/aarch64/h264: revert ctx flip — daedalus-fourier PR
#36 was a measurement artifact
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Reverts the daedalus_ctx_create_no_qpu() → daedalus_ctx_create() flip
that landed in 0014-h264-ctx-qpu-capable.patch (marfrit-packages PR
#104). The flip was justified by daedalus-fourier PR #36 which
reported a 4.30x QPU-over-CPU win on the 1080p H.264 hot-path sum.
That number was a measurement artifact. The bench tool's
v3d_runner.read_spv() did a bare fopen() that resolved relative to
cwd; when run from the source directory (as in PR #36), the SPVs at
$builddir/v3d_*.spv were not found, every QPU dispatch returned -1
fast, and the loop timed the failure path. Daedalus-fourier PR #37
fixes the SPV search + bench preflight; corrected numbers from hertz
(Pi 5 V3D 7.1) show QPU is 12-77x SLOWER than CPU NEON at every
H.264 hot-path kernel:
kernel CPU ns/op QPU ns/op winner
IDCT 4x4 luma 10.75 217.63 CPU 20.24x
IDCT 8x8 luma 29.69 785.94 CPU 26.47x
Deblock luma_v 17.63 467.42 CPU 26.51x
Deblock luma_h 38.30 498.53 CPU 13.02x
qpel mc20 (8x8) 30.17 1300.44 CPU 43.10x
qpel mc02 (8x8) 17.69 1363.40 CPU 77.08x
qpel mc22 (8x8) 71.60 1948.37 CPU 27.21x
1080p sum: CPU 5.57 ms vs QPU 123.54 ms — QPU 22x slower.
Until the daedalus QPU dispatch overhead is actually competitive (a
multi-task effort tracked on the daedalus-fourier side), the
libavcodec.so substitution must stay on daedalus_ctx_create_no_qpu()
to avoid pessimizing every host process that loads it
(firefox-fourier RDD, mpv-fourier, daedalus_v4l2_daemon).
Both H.264 TUs (h264_idct_daedalus.c, h264_qpel_daedalus.c) are
reverted; the change is a 2-line revert of patch 0014.
Refs reauktion/daedalus-fourier!37 (the retraction PR).
---
libavcodec/aarch64/h264_idct_daedalus.c | 2 +-
libavcodec/aarch64/h264_qpel_daedalus.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/libavcodec/aarch64/h264_idct_daedalus.c b/libavcodec/aarch64/h264_idct_daedalus.c
--- a/libavcodec/aarch64/h264_idct_daedalus.c
+++ b/libavcodec/aarch64/h264_idct_daedalus.c
@@ -32,7 +32,7 @@ static pthread_once_t g_dctx_once = PTHREAD_ONCE_INIT;
static void daedalus_ctx_init_once(void)
{
- g_dctx = daedalus_ctx_create();
+ g_dctx = daedalus_ctx_create_no_qpu();
}
void ff_h264_idct_add_daedalus(uint8_t *dst, int16_t *block, int stride);
diff --git a/libavcodec/aarch64/h264_qpel_daedalus.c b/libavcodec/aarch64/h264_qpel_daedalus.c
--- a/libavcodec/aarch64/h264_qpel_daedalus.c
+++ b/libavcodec/aarch64/h264_qpel_daedalus.c
@@ -38,7 +38,7 @@ static pthread_once_t g_dctx_once = PTHREAD_ONCE_INIT;
static void daedalus_ctx_init_once(void)
{
- g_dctx = daedalus_ctx_create();
+ g_dctx = daedalus_ctx_create_no_qpu();
}
void ff_put_h264_qpel8_mc20_daedalus(uint8_t *dst, const uint8_t *src, ptrdiff_t stride);
@@ -0,0 +1,132 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Markus Fritsche <mfritsche@reauktion.de>
Date: Tue, 26 May 2026 06:00:00 +0200
Subject: [PATCH] avcodec/h264: per-MB inspection callback (daedalus-decoder
hook)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Adds an opt-in callback fired in ff_h264_hl_decode_mb after the
existing pixel work, used by tools that need per-MB visibility into
the H.264 decode. Initially driven by daedalus-decoder's CLI test
harness (tools/daedalus_decode_h264) which shadows libavcodec's
decode with a frame-major daedalus-decoder run for byte-exact diff
on real H.264 streams; later target is a daedalus-v4l2 daemon
refactor that drives daedalus_decoder_append_mb directly from the
callback instead of letting libavcodec do per-MB pixel work.
Shape: ONE inspection point per MB. Distinct from the per-kernel
function-pointer-hijack pattern that used to live in 0003-0014
patches (now reverted via 0015 for ctx, and architecturally retired
per daedalus-fourier PR #37's measurement-correction). Per-block
synchronous Vulkan dispatch from libavcodec was structurally non-
competitive; per-MB CPU-side observation feeding a per-frame batch
submit is the right shape.
Two new fields in H264Context (appended at end of struct; no ABI
surface visible to non-libavcodec callers since H264Context is
internal — declared in h264dec.h, not h264.h). One new exported
function ff_h264_set_mb_inspect_cb to set them.
Zero behaviour change when cb == NULL (the default): one load +
one branch per MB in the decoder hot path, both branch-predicted
to fall through.
Used by:
- daedalus-decoder/tools/daedalus_decode_h264 (PR-A1b)
- daedalus-v4l2 daemon shadow-mode path (PR-Q3a.1+)
The CLI static-links libavcodec.a so symbol visibility doesn't matter
there. The daemon dlopens libavcodec.so.62 and resolves the callback
via dlsym, so the symbol MUST be exported — added to libavcodec.v
explicitly (FFmpeg's default version script hides every `ff_*` symbol
as LOCAL behind a glob).
Refs reauktion/daedalus-decoder!12 (Stage 2 PR-b complete).
---
libavcodec/h264_mb.c | 20 ++++++++++++++++++++
libavcodec/h264dec.h | 26 ++++++++++++++++++++++++++
libavcodec/libavcodec.v | 1 +
3 files changed, 47 insertions(+)
--- a/libavcodec/h264dec.h
+++ b/libavcodec/h264dec.h
@@ -334,6 +334,16 @@
int pic_order_cnt_bit_size;
} H264SliceContext;
+/* Per-MB inspection callback type — see ff_h264_set_mb_inspect_cb()
+ * below. Fired by ff_h264_hl_decode_mb after the existing pixel work
+ * for every macroblock in coded order. Receives a const H264Context*
+ * so the callback can inspect any slice/picture state (h->slice_ctx
+ * for current slice, h->cur_pic.f->data[plane] for reconstructed
+ * samples, etc.). */
+typedef void (*ff_h264_mb_inspect_cb)(void *opaque,
+ const struct H264Context *h,
+ int mb_x, int mb_y);
+
/**
* H264Context
*/
@@ -579,6 +589,10 @@
int non_gray; ///< Did we encounter a intra frame after a gray gap frame
int noref_gray;
int skip_gray;
+
+ /* Per-MB inspection hook — set via ff_h264_set_mb_inspect_cb. */
+ ff_h264_mb_inspect_cb mb_inspect_cb;
+ void *mb_inspect_opaque;
} H264Context;
extern const uint16_t ff_h264_mb_sizes[4];
@@ -607,6 +621,16 @@
const H2645NAL *nal, void *logctx);
void ff_h264_hl_decode_mb(const H264Context *h, H264SliceContext *sl);
+
+/**
+ * Install an opt-in per-MB inspection callback that fires from
+ * ff_h264_hl_decode_mb after each macroblock's pixel work. Default
+ * is NULL (no callback installed); the check is a single branch on
+ * the decoder hot path. See ff_h264_mb_inspect_cb for signature.
+ */
+void ff_h264_set_mb_inspect_cb(AVCodecContext *avctx,
+ ff_h264_mb_inspect_cb cb, void *opaque);
+
void ff_h264_decode_init_vlc(void);
/**
--- a/libavcodec/h264_mb.c
+++ b/libavcodec/h264_mb.c
@@ -815,4 +815,20 @@
hl_decode_mb_simple_16(h, sl);
} else
hl_decode_mb_simple_8(h, sl);
+
+ /* Per-MB inspection callback (opt-in via ff_h264_set_mb_inspect_cb).
+ * Fired AFTER pixel work — reconstructed samples are in
+ * h->cur_pic.f->data[plane] at the MB's raster position by the
+ * time this runs. Callback may inspect slice context via
+ * h->slice_ctx + sl->mb_xy, coeffs via sl->mb, etc. */
+ if (h->mb_inspect_cb)
+ h->mb_inspect_cb(h->mb_inspect_opaque, h, sl->mb_x, sl->mb_y);
+}
+
+void ff_h264_set_mb_inspect_cb(AVCodecContext *avctx,
+ ff_h264_mb_inspect_cb cb, void *opaque)
+{
+ H264Context *h = avctx->priv_data;
+ h->mb_inspect_cb = cb;
+ h->mb_inspect_opaque = opaque;
}
--- a/libavcodec/libavcodec.v
+++ b/libavcodec/libavcodec.v
@@ -3,6 +3,7 @@
av_*;
avcodec_*;
avpriv_*;
+ ff_h264_set_mb_inspect_cb;
avsubtitle_free;
local:
*;
@@ -0,0 +1,88 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Markus Fritsche <mfritsche@reauktion.de>
Date: Tue, 26 May 2026 07:30:00 +0200
Subject: [PATCH] avcodec/h264: preserve sl->mb coefficients for the inspection
callback (companion to 0016)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Patch 0016 adds a per-MB inspection callback fired at the end of
ff_h264_hl_decode_mb. By that time the IDCT-add path has already
zeroed sl->mb (FFmpeg's convention — see ff_h264_idct_add_neon and
friends), so consumers reading coefficients from the callback get
zeros.
Add a coefficient side buffer in H264Context, populated at the
START of ff_h264_hl_decode_mb (before any IDCT runs) with a single
memcpy from sl->mb. The post-pixel-work callback (still in 0016)
can then read both:
- the side-buffer coefficients (= just-entropy-decoded, pre-IDCT)
- the reconstructed pixels in h->cur_pic.f->data (= P + IDCT(C),
pre-deblock for this MB)
and the consumer can derive P = pixels IDCT(C) for daedalus-
decoder's frame-major dispatch.
Memcpy is gated on (h->mb_inspect_cb != NULL) — zero overhead when
no consumer is registered. Buffer size = sizeof(int16_t) * 16 * 48
= 1536 bytes per H264Context (fits in one cache line family;
allocated once at H264Context lifetime, reused per MB).
8-bit path only. High-bit-depth H.264 uses the upper half of
sl->mb (int16_t[16 * 48 * 2] declared; the * 2 reserves space for
the high-depth case); preserving the high-depth coefficients
correctly would need a wider side buffer. Punted for now — the
daedalus-decoder consumer is 8-bit-only.
Single-threaded decode assumed at the consumer side (avctx->
thread_count = 1). Multi-slice / multi-threaded streams would
race on the single side buffer — that's an explicit limitation of
the inspection mechanism, documented in 0016's comment block.
Future extension: per-H264SliceContext side buffers.
Used by:
- daedalus-decoder/tools/daedalus_decode_h264 PR-A3+ (CLI test
harness extracts coefficients here for daedalus-decoder
IDCT validation on real H.264 streams).
Refs reauktion/daedalus-decoder!14 (PR-A2 callback wiring).
---
libavcodec/h264_mb.c | 9 +++++++++
libavcodec/h264dec.h | 8 ++++++++
2 files changed, 17 insertions(+)
--- a/libavcodec/h264dec.h
+++ b/libavcodec/h264dec.h
@@ -593,6 +593,14 @@
/* Per-MB inspection hook — set via ff_h264_set_mb_inspect_cb. */
ff_h264_mb_inspect_cb mb_inspect_cb;
void *mb_inspect_opaque;
+
+ /* Per-MB coefficient side buffer — populated at the start of
+ * ff_h264_hl_decode_mb so the post-pixel-work inspection callback
+ * can read the just-entropy-decoded coefficients before IDCT-add
+ * zeros sl->mb. 16 blocks × 48 int16 = libavcodec sl->mb size
+ * (matches DECLARE_ALIGNED(16, int16_t, mb)[16 * 48 * 2] for the
+ * 8-bit half; high-bit-depth paths skip this — see h264_mb.c). */
+ DECLARE_ALIGNED(16, int16_t, mb_inspect_coeffs)[16 * 48];
} H264Context;
extern const uint16_t ff_h264_mb_sizes[4];
--- a/libavcodec/h264_mb.c
+++ b/libavcodec/h264_mb.c
@@ -801,6 +801,15 @@
{
const int mb_xy = sl->mb_xy;
const int mb_type = h->cur_pic.mb_type[mb_xy];
+
+ /* Snapshot just-entropy-decoded coefficients before IDCT-add
+ * destroys them. Only when an inspection callback is registered
+ * — zero cost otherwise. 8-bit path only (high-bit-depth uses
+ * the upper half of sl->mb which we don't preserve here). */
+ if (h->mb_inspect_cb && !h->pixel_shift)
+ memcpy((int16_t *) (uintptr_t) h->mb_inspect_coeffs, sl->mb,
+ sizeof(((H264Context *) NULL)->mb_inspect_coeffs));
+
int is_complex = CONFIG_SMALL || sl->is_complex ||
IS_INTRA_PCM(mb_type) || sl->qscale == 0;
+8 -6
View File
@@ -33,12 +33,10 @@ FFMPEG_VERSION=8.1
# epoch 2 matches Debian's stock ffmpeg (currently 7:7.1.x in trixie);
# +rfourier suffix to avoid colliding with upstream/Debian rebuilds.
PKGVER=2:${FFMPEG_VERSION}+rfourier+gb57fbbe
PKGREL=10 # pkgrel=10H.264 luma qpel mc20 daedalus-fourier substitution
# (cycle 9 of the daedalus-v4l2#11 step 2 substitution arc; closes
# the libavcodec.so substitution sequence 6 IDCT4 / 7 IDCT8 /
# 8 luma-v deblock / 9 qpel mc20). Pulls daedalus-fourier PR #2
# which extends the public API with
# daedalus_recipe_dispatch_h264_qpel_mc20. (2026-05-23)
PKGREL=15 # pkgrel=15export ff_h264_set_mb_inspect_cb via libavcodec.v so
# dlsym consumers (daedalus-v4l2 daemon shadow_decoder, PR-Q3a.1)
# can resolve the symbol; static-link CLI was unaffected. No
# behaviour change to existing decode path. (2026-05-26)
# daedalus-fourier pin. 209a421 = daedalus-fourier PR #2 merge — public
# API now exposes daedalus_recipe_dispatch_h264_qpel_mc20 +
@@ -80,6 +78,10 @@ patch -Np1 -i "$HERE/0010-h264-deblock-luma-intra-daedalus-fourier.patch"
patch -Np1 -i "$HERE/0011-h264-chroma-dc-hadamard-daedalus-fourier.patch"
patch -Np1 -i "$HERE/0012-h264-qpel-rest-daedalus-fourier.patch"
patch -Np1 -i "$HERE/0013-h264-deblock-chroma-intra-daedalus-fourier.patch"
patch -Np1 -i "$HERE/0014-h264-ctx-qpu-capable.patch"
patch -Np1 -i "$HERE/0015-h264-ctx-revert-to-no-qpu.patch"
patch -Np1 -i "$HERE/0016-h264-mb-inspect-callback.patch"
patch -Np1 -i "$HERE/0017-h264-mb-coeffs-side-buffer.patch"
# --- daedalus-fourier: fetch + build static .a with PIC, install to a
# per-build prefix; libavcodec.so links it into the shared object so
+18
View File
@@ -1,3 +1,21 @@
ffmpeg-v4l2-request-fourier (2:8.1+rfourier+gb57fbbe-15) bookworm trixie; urgency=medium
* Amend 0016-h264-mb-inspect-callback.patch to also add
ff_h264_set_mb_inspect_cb to libavcodec/libavcodec.v so the
symbol is exported (GLOBAL) on the shipped libavcodec.so.62.
Without this, FFmpeg's default version script hides every ff_*
symbol behind a glob → LOCAL → dlsym() returns NULL. The CLI
consumer (daedalus_decode_h264) was unaffected because it
static-links libavcodec.a; the daedalus-v4l2 daemon (PR-Q3a.1
shadow_decoder path) dlopens libavcodec.so.62 and needs the
symbol resolvable at runtime.
* No behaviour change to existing decode path. Callback is still
opt-in via the function pointer (NULL default), so paying the
one-load-one-branch cost only when a consumer has explicitly
installed an inspection callback.
-- Markus Fritsche <mfritsche@reauktion.de> Tue, 26 May 2026 15:00:00 +0200
ffmpeg-v4l2-request-fourier (2:8.1+rfourier+gb57fbbe-10) bookworm trixie; urgency=medium
* Add 0007-h264-qpel-mc20-daedalus-fourier.patch —
+5 -7
View File
@@ -7,10 +7,10 @@
# package (Architecture: all, depends on lua + lua-socket).
set -euo pipefail
PKGVER=1.2.1
UPSTREAM_TAG=v1.2.1
PKGVER=1.2.4
UPSTREAM_TAG=v1.2.4
PKGREL=1
LMCP_TARBALL_SHA256=bf9cce1a84c66b1b74c5aec923c5960d60ae33c221afc8d47ce0d74b8f7ee609
LMCP_TARBALL_SHA256=e8ede94e93f5f2bbc8bacbc795c17640772ecd62855e820394c00f2f3be5b42c
HERE=$(dirname "$(readlink -f "$0")")
# Reproducible build: pin all file mtimes + ar member timestamps to a fixed
@@ -28,15 +28,13 @@ echo "$LMCP_TARBALL_SHA256 lmcp.tar.gz" | sha256sum -c
tar xzf lmcp.tar.gz
ROOT="$work/pkgroot"
mkdir -p "$ROOT/DEBIAN" \
"$ROOT/usr/share/lua/5.4" \
"$ROOT/usr/bin" \
"$ROOT/usr/share/doc/lmcp"
mkdir -p "$ROOT/DEBIAN" "$ROOT/usr/share/lua/5.4" "$ROOT/usr/bin" "$ROOT/usr/share/doc/lmcp"
cp lmcp/lmcp.lua "$ROOT/usr/share/lua/5.4/"
cp lmcp/json.lua "$ROOT/usr/share/lua/5.4/"
cp lmcp/server.lua "$ROOT/usr/share/lua/5.4/"
cp lmcp/hub.lua "$ROOT/usr/share/lua/5.4/"
cp lmcp/tools.d/nash.lua "$ROOT/usr/share/lua/5.4/nash.lua"
mkdir -p "$ROOT/usr/share/doc/lmcp/examples"
cp lmcp/examples/lmcp-hub.service "$ROOT/usr/share/doc/lmcp/examples/"
cp lmcp/examples/lmcp.service "$ROOT/usr/share/doc/lmcp/examples/"
+28 -1
View File
@@ -1,3 +1,30 @@
lmcp (1.2.4-1) bookworm trixie; urgency=medium
* shell/shell_bg: kill the whole process group (setsid + SIGTERM/SIGKILL)
on timeout or client cancel, so a timed-out command leaves no orphan
process thrashing the host (fixes the shell->shell_bg relaunch pileup).
* Add kill_job and list_jobs tools to reap runaway background jobs
(registry at /tmp/lmcp-bg-jobs.tsv) without a reboot.
-- Markus Fritsche <mfritsche@reauktion.de> Sun, 12 Jul 2026 21:05:38 +0000
lmcp (1.2.3-1) bookworm trixie; urgency=medium
* Add nash memory tools plugin (tools.d/nash.lua): 4 tools
(nash_add, nash_search, nash_list, nash_delete) backed by
mem0 REST API at NASH_URL env var.
* Package installs nash.lua alongside the other lua libs at
/usr/share/lua/5.4/nash.lua.
-- Markus Fritsche <mfritsche@reauktion.de> Fri, 05 Jun 2026 16:00:00 +0000
lmcp (1.2.2-1) bookworm trixie; urgency=medium
* case-insensitive Bearer auth header (lmcp#25): regex ^Bearer → ^[Bb]earer
so clients sending lowercase 'bearer' don't get spurious 401s.
-- Markus Fritsche <mfritsche@reauktion.de> Sat, 30 May 2026 14:52:16 +0000
lmcp (1.2.1-1) bookworm trixie; urgency=medium
* tools.d/ plugin scan (closes lmcp#22): server.lua now scans
@@ -151,4 +178,4 @@ lmcp (0.3.0-1) bookworm trixie; urgency=medium
* Initial release packaged for marfrit overlay repo.
-- Markus Fritsche <mfritsche@reauktion.de> Tue, 14 Apr 2026 22:00:00 +0200
-- Markus Fritsche <mfritsche@reauktion.de> Tue, 14 Apr 2026 22:00:00 +0200
+60
View File
@@ -0,0 +1,60 @@
#!/bin/bash
# Build reauktion-home-ca_<ver>_all.deb from this directory using dpkg-deb
# directly. Run from inside the runner container, which has dpkg installed.
#
# No upstream tarball: this is PKI trust material (the reauktion.de Home CA
# root cert), not software with its own release cadence. The .crt is
# committed alongside this script instead of being fetched.
set -euo pipefail
PKGVER=20260716
PKGREL=1
HERE=$(dirname "$(readlink -f "$0")")
# Reproducible build: pin all file mtimes + ar member timestamps so repeat
# builds produce identical bytes (reprepro refuses re-includes otherwise).
export SOURCE_DATE_EPOCH=1784505600
work=$(mktemp -d)
trap "rm -rf $work" EXIT
ROOT="$work/pkgroot"
mkdir -p "$ROOT/DEBIAN" \
"$ROOT/usr/local/share/ca-certificates" \
"$ROOT/usr/share/doc/reauktion-home-ca"
install -m 644 "$HERE/reauktion-home-ca.crt" \
"$ROOT/usr/local/share/ca-certificates/reauktion-home-ca.crt"
cp "$HERE/debian/copyright" "$ROOT/usr/share/doc/reauktion-home-ca/copyright"
cp "$HERE/debian/changelog" "$ROOT/usr/share/doc/reauktion-home-ca/changelog.Debian"
gzip -9 -n "$ROOT/usr/share/doc/reauktion-home-ca/changelog.Debian"
install -m 755 "$HERE/debian/postinst" "$ROOT/DEBIAN/postinst"
install -m 755 "$HERE/debian/postrm" "$ROOT/DEBIAN/postrm"
cat > "$ROOT/DEBIAN/control" <<EOF
Package: reauktion-home-ca
Version: ${PKGVER}-${PKGREL}
Section: admin
Priority: optional
Architecture: all
Depends: ca-certificates
Maintainer: Markus Fritsche <mfritsche@reauktion.de>
Homepage: https://git.reauktion.de/marfrit/marfrit-packages
Description: reauktion.de Home CA trust anchor for internal *.fritz.box HTTPS
Installs the private, name-constrained root CA used to sign internal
*.fritz.box and reauktion.de HTTPS services, so clients don't need -k
or browser exceptions to reach them.
.
Name constraints permit only fritz.box, reauktion.de, and localhost —
a leaked key can forge certificates for no other domain.
.
SHA256 fingerprint:
A3:32:17:6D:17:CF:F7:24:23:05:88:E0:6A:5E:5A:37:82:B9:BA:B5:BC:A1:2E:52:E3:88:3C:54:19:8B:F9:86
EOF
# Build the .deb. Output to current dir of the caller.
DEB_OUT=reauktion-home-ca_${PKGVER}-${PKGREL}_all.deb
dpkg-deb --root-owner-group --build "$ROOT" "$HERE/$DEB_OUT"
echo "built: $HERE/$DEB_OUT"
+9
View File
@@ -0,0 +1,9 @@
reauktion-home-ca (20260716-1) bookworm trixie; urgency=medium
* Initial release. Trust anchor for the reauktion.de Home CA (created
2026-07-16 on hertz:/opt/herding/pki/), a name-constrained root
permitted only for fritz.box, reauktion.de, and localhost. Installs
to /usr/local/share/ca-certificates/ and runs update-ca-certificates
on install/remove via maintainer scripts.
-- Markus Fritsche <mfritsche@reauktion.de> Mon, 20 Jul 2026 00:00:00 +0000
+18
View File
@@ -0,0 +1,18 @@
Package: reauktion-home-ca
Version: 20260716-1
Section: admin
Priority: optional
Architecture: all
Depends: ca-certificates
Maintainer: Markus Fritsche <mfritsche@reauktion.de>
Homepage: https://git.reauktion.de/marfrit/marfrit-packages
Description: reauktion.de Home CA trust anchor for internal *.fritz.box HTTPS
Installs the private, name-constrained root CA used to sign internal
*.fritz.box and reauktion.de HTTPS services, so clients don't need -k
or browser exceptions to reach them.
.
Name constraints permit only fritz.box, reauktion.de, and localhost —
a leaked key can forge certificates for no other domain.
.
SHA256 fingerprint:
A3:32:17:6D:17:CF:F7:24:23:05:88:E0:6A:5E:5A:37:82:B9:BA:B5:BC:A1:2E:52:E3:88:3C:54:19:8B:F9:86
+9
View File
@@ -0,0 +1,9 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: reauktion-home-ca
Source: https://git.reauktion.de/marfrit/marfrit-packages
Files: *
Copyright: 2026 Markus Fritsche <mfritsche@reauktion.de>
License: proprietary
Private PKI trust material for the reauktion.de / fritz.box fleet.
Not for redistribution outside that fleet.
+8
View File
@@ -0,0 +1,8 @@
#!/bin/sh
set -e
if [ "$1" = "configure" ]; then
update-ca-certificates
fi
exit 0
+8
View File
@@ -0,0 +1,8 @@
#!/bin/sh
set -e
if [ "$1" = "remove" ] || [ "$1" = "purge" ]; then
update-ca-certificates
fi
exit 0
+33
View File
@@ -0,0 +1,33 @@
-----BEGIN CERTIFICATE-----
MIIFsTCCA5mgAwIBAgIUTAWmENkKSdBtjEqN55mD2S96BbMwDQYJKoZIhvcNAQEL
BQAwQjEVMBMGA1UECgwMcmVhdWt0aW9uLmRlMSkwJwYDVQQDDCByZWF1a3Rpb24u
ZGUgSG9tZSBDQSAoZnJpdHouYm94KTAeFw0yNjA3MTYyMTMzMjZaFw00NjA3MTEy
MTMzMjZaMEIxFTATBgNVBAoMDHJlYXVrdGlvbi5kZTEpMCcGA1UEAwwgcmVhdWt0
aW9uLmRlIEhvbWUgQ0EgKGZyaXR6LmJveCkwggIiMA0GCSqGSIb3DQEBAQUAA4IC
DwAwggIKAoICAQCoXQg4BEvZ7PDZMvnRJtESFBPtWsdNFQz+YT1Z/mhWnNyAgfkY
AQ5f9yzegyDrDdnm/nzv6h1Zpss+S6TE29lnLGtXaMnkNsLpdvnIi8j0Wgi2+DkA
A9JTkvoDrgn9yJWcG9tFj6BPex4VvLUK55luFiv+y+2e/Xg6z4zhMJe0PwoUkb3+
lUsBnNHbBQF2bH1suJx3xVgAdpZTpqBp/bfDyj0RgokSnD17jlxF2xC3nY3lCJ1M
l676xToeoAMvDcGc0zjKwno/JtvB/ZzfF7jPNV47czMYboCpa7lSDtjwmCLpeVkP
6HvXcg1riER+aLC1urGLNtC2hMiSBmjlm0KZfxdTZj9J1hHLUynlYCc+jHYfSXKS
rP6i3EV4fKuMeuFyt/ribHMv+fsI2Te7IwOBA4VQg/d+q6qwTcRO09MJzEDtY5OU
4EPlLvd2nNKeF3u0qCn+2t7TmIK9dpi4gVmxhnCRlD1SLDfwnznMiDydtZJr/Kh7
rjKgTCBAulfS9N4RQ0kyFM9hPF2KNYu8Ef6DRb3wysN1W0ozs+sdYQA15hczEFDu
gVxTcwQEd4B+1seUWsDKDqRogZHLoNVrPVWp+sK4E5msyLjHzcqTBt0tpVK+2ztq
CgkwnmNPcexevrkkPz4PuxpwqDpEJ3CLutu/RCAwSZZGSM8q0ViIXreRcwIDAQAB
o4GeMIGbMB8GA1UdIwQYMBaAFOT/M0xih1hOVqUu1dujtbAmfEjZMA8GA1UdEwEB
/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTk/zNMYodYTlalLtXb
o7WwJnxI2TA4BgNVHR4BAf8ELjAsoCowC4IJZnJpdHouYm94MA6CDHJlYXVrdGlv
bi5kZTALgglsb2NhbGhvc3QwDQYJKoZIhvcNAQELBQADggIBAI76BcH2ATaiSwUj
yleSzhvFB2HjOjdQimo4vt6O6YWagYXXijC3VUJ2fY5/x/S20WuVXONfqVvBKmi9
p7x/oz/UsmLtn/SHy253a37Uf62EV++JgNiaf1GuJXjgRAxtQ3fsWY3qw906yjN9
2BqFBRRcX026HU7a9b921VCp1D8qDa43kIi9T69Fl+pNKYb2XJYda8EpehStK/02
BQr2Owp3QGWBly5w+cjB1E77PhFYLb4jzPe2eDDs01zoDZ/IVaf2jPWiG+dGmV2Q
J1O7u5OacwWS4WjhWYIMG3XSbkZkCIrrJFuKNEabhYlS9GxySfDn3vovWQQsJf6n
uoeCOI/dN08snps2XMoaMbl8TeqrityQnDKhX5k8sxvO8/IrpHt4766YBHMcwcIr
vU1zc9Yls5vOMc5adAGGj3WloCCtzTOiDPQC952nmA+8e6Pla4u4GFvwArS+LfKG
R7c7pN6Q61bVRhM4liQ6n9djkaGuXSfkrjcWy+JsjyesHG62TxhUNDY7kqEo8V52
oVFxWkZClQN0f5kxeXuPV+LCby4YiDq8kTkXp8jE0OvpPx4WR4pUG/nHBOE1O0b7
GQTHwKaJs/CtfuwfJRk7ACjwEdV8G8mQxgRJB6e+pZMGqbigqWPcPTR9tnjdbg4V
PMS6m3J+HDRSK/22ACSisUhJIQNL
-----END CERTIFICATE-----
+65
View File
@@ -0,0 +1,65 @@
#!/bin/bash
# Build sic-agent_<ver>_<arch>.deb using dpkg-deb (Go cross-build of the client
# plus the agent skills).
#
# Usage: ./build-deb.sh [amd64|arm64] (default: host dpkg architecture)
# Needs: go, dpkg-deb, curl.
set -euo pipefail
PKGVER=0.2.1
PKGREL=1
SIC_TARBALL_SHA256=0efe5acc0218fab02faf0c3c6f8cc1bcd57de64d0bff64bd08affe293b4f0bb6
HERE=$(dirname "$(readlink -f "$0")")
DEB_ARCH="${1:-$(dpkg --print-architecture)}"
case "$DEB_ARCH" in
amd64) GOARCH=amd64 ;;
arm64) GOARCH=arm64 ;;
*) echo "unsupported arch: $DEB_ARCH (use amd64 or arm64)" >&2; exit 1 ;;
esac
export SOURCE_DATE_EPOCH=1784829600
work=$(mktemp -d)
trap "rm -rf $work" EXIT
cd "$work"
curl -sSLfo sic.tar.gz \
"https://git.reauktion.de/marfrit/sic/archive/v${PKGVER}.tar.gz"
echo "$SIC_TARBALL_SHA256 sic.tar.gz" | sha256sum -c
tar xzf sic.tar.gz
( cd sic && GOOS=linux GOARCH="$GOARCH" CGO_ENABLED=0 \
GOFLAGS='-buildvcs=false -trimpath' go build -ldflags='-s -w' -o sic ./cmd/sic )
ROOT="$work/pkgroot"
mkdir -p "$ROOT/DEBIAN" "$ROOT/usr/bin" \
"$ROOT/usr/share/sic-agent/skills/sic" \
"$ROOT/usr/share/sic-agent/skills/sic-bg" \
"$ROOT/usr/share/doc/sic-agent"
install -m755 sic/sic "$ROOT/usr/bin/sic"
install -m644 sic/SKILL.md "$ROOT/usr/share/sic-agent/skills/sic/SKILL.md"
install -m644 sic/SKILL-bg.md "$ROOT/usr/share/sic-agent/skills/sic-bg/SKILL.md"
install -m644 sic/README.md "$ROOT/usr/share/doc/sic-agent/README.md"
install -m644 "$HERE/debian/copyright" "$ROOT/usr/share/doc/sic-agent/copyright"
{
echo "Package: sic-agent"
echo "Version: ${PKGVER}-${PKGREL}"
echo "Architecture: ${DEB_ARCH}"
echo "Maintainer: Markus Fritsche <mfritsche@reauktion.de>"
echo "Section: net"
echo "Priority: optional"
echo "Depends: openssh-client"
echo "Homepage: https://git.reauktion.de/marfrit/sic"
echo "Description: sic client and agent skills for remote command execution"
echo " The sic client frames argv as netstrings and pipes it over ssh to"
echo " sicd on a remote host. Installs /usr/bin/sic and foreground/background"
echo " agent skills under /usr/share/sic-agent/skills/; link them into the"
echo " agent's skills directory to activate. Targets need the sicd package."
} > "$ROOT/DEBIAN/control"
OUT="$HERE/sic-agent_${PKGVER}-${PKGREL}_${DEB_ARCH}.deb"
rm -f "$OUT"
dpkg-deb --root-owner-group --build "$ROOT" "$OUT"
echo "built $OUT"
+22
View File
@@ -0,0 +1,22 @@
sic-agent (0.2.1-1) unstable; urgency=low
* Version bump only (shares the sic v0.2.1 tag). No client changes; the fix is in sicd.
-- Markus Fritsche <mfritsche@reauktion.de> Thu, 23 Jul 2026 18:00:00 +0000
sic-agent (0.2.0-1) unstable; urgency=low
* Client rewritten onto the v2 wire: nested `host/hop1/hop2` targets resolved
via /etc/sic/hosts.toml, boundary-preserved argv ([][]byte, never space-
joined; --sh is the sole shell-line exception). Now forwards stdin AFTER the
frame — fixes the v0.1.0 trap where `sic host 'cat >f' <local` wrote a
zero-byte file and reported success. `ssh -T` (binary-safe frame), exit
status inherited. Reviewed (bullpen 964/970).
-- Markus Fritsche <mfritsche@reauktion.de> Thu, 23 Jul 2026 12:00:00 +0000
sic-agent (0.1.0-1) unstable; urgency=low
* Initial release: sic client plus foreground/background agent skills.
-- Markus Fritsche <mfritsche@reauktion.de> Sat, 19 Jul 2026 12:00:00 +0000
+19
View File
@@ -0,0 +1,19 @@
Source: sic-agent
Section: net
Priority: optional
Maintainer: Markus Fritsche <mfritsche@reauktion.de>
Build-Depends: debhelper-compat (= 13), golang-go
Standards-Version: 4.6.2
Homepage: https://git.reauktion.de/marfrit/sic
Package: sic-agent
Architecture: any
Depends: ${misc:Depends}, openssh-client
Description: sic client and agent skills for remote command execution
The sic client frames argv as netstrings and pipes it over ssh to sicd on a
remote host, which runs it with execvp — no shell re-parses the arguments.
.
Installs /usr/bin/sic and two agent skills (foreground and background remote
exec) under /usr/share/sic-agent/skills/. Link the skills into the agent's
skills directory (for example ~/.claude/skills/) to activate them. The target
hosts need the sicd package.
+26
View File
@@ -0,0 +1,26 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: sic
Source: https://git.reauktion.de/marfrit/sic
Files: *
Copyright: 2026 marfrit
License: MIT
License: MIT
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
.
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Vendored Executable
+61
View File
@@ -0,0 +1,61 @@
#!/bin/bash
# Build sicd_<ver>_<arch>.deb using dpkg-deb. Mirrors the lmcp/claude-his-agent
# pattern, plus a Go cross-build step (sicd is a compiled binary).
#
# Usage: ./build-deb.sh [amd64|arm64] (default: host dpkg architecture)
# Needs: go, dpkg-deb, curl.
set -euo pipefail
PKGVER=0.2.1
PKGREL=1
SIC_TARBALL_SHA256=0efe5acc0218fab02faf0c3c6f8cc1bcd57de64d0bff64bd08affe293b4f0bb6
HERE=$(dirname "$(readlink -f "$0")")
DEB_ARCH="${1:-$(dpkg --print-architecture)}"
case "$DEB_ARCH" in
amd64) GOARCH=amd64 ;;
arm64) GOARCH=arm64 ;;
*) echo "unsupported arch: $DEB_ARCH (use amd64 or arm64)" >&2; exit 1 ;;
esac
# Reproducible build: pin mtimes + ar timestamps (v0.1.0, 2026-07-19 12:00 UTC).
export SOURCE_DATE_EPOCH=1784829600
work=$(mktemp -d)
trap "rm -rf $work" EXIT
cd "$work"
curl -sSLfo sic.tar.gz \
"https://git.reauktion.de/marfrit/sic/archive/v${PKGVER}.tar.gz"
echo "$SIC_TARBALL_SHA256 sic.tar.gz" | sha256sum -c
tar xzf sic.tar.gz
( cd sic && GOOS=linux GOARCH="$GOARCH" CGO_ENABLED=0 \
GOFLAGS='-buildvcs=false -trimpath' go build -ldflags='-s -w' -o sicd ./cmd/sicd )
ROOT="$work/pkgroot"
mkdir -p "$ROOT/DEBIAN" "$ROOT/usr/bin" "$ROOT/usr/share/doc/sicd"
install -m755 sic/sicd "$ROOT/usr/bin/sicd"
install -m644 sic/gateway/sicd "$ROOT/usr/share/doc/sicd/sicd-reference.py"
install -m644 sic/docs/design.md "$ROOT/usr/share/doc/sicd/design.md"
install -m644 "$HERE/debian/copyright" "$ROOT/usr/share/doc/sicd/copyright"
{
echo "Package: sicd"
echo "Version: ${PKGVER}-${PKGREL}"
echo "Architecture: ${DEB_ARCH}"
echo "Maintainer: Markus Fritsche <mfritsche@reauktion.de>"
echo "Section: net"
echo "Priority: optional"
echo "Recommends: openssh-server"
echo "Homepage: https://git.reauktion.de/marfrit/sic"
echo "Description: sic daemon — netstring argv over stdin, execvp'd"
echo " sicd reads netstring-framed argv from stdin and runs it with execvp,"
echo " so no shell re-parses the arguments. Deploy on target hosts and run"
echo " it over ssh (as the remote command, or command=\"sicd\" on a key)."
} > "$ROOT/DEBIAN/control"
OUT="$HERE/sicd_${PKGVER}-${PKGREL}_${DEB_ARCH}.deb"
rm -f "$OUT"
dpkg-deb --root-owner-group --build "$ROOT" "$OUT"
echo "built $OUT"
+30
View File
@@ -0,0 +1,30 @@
sicd (0.2.1-1) unstable; urgency=medium
* Fix a hang: the daemon's stdin pump blocked on the ssh stdin channel long after the child
command had exited, when the v2 client forwarded a stdin that never EOFs (a caller holding
the pipe open). sicd now races the stdin copy against the child's exit and reaps on
child-exit (like ssh itself), so `sic host cmd` returns as soon as cmd finishes instead of
hanging until stdin close or a timeout. Piped/redirected stdin still forwards; a genuine
truncation to a still-reading child is still a non-zero failure. Daemon-only; client
unchanged; v1/v2 dual-read unaffected.
-- Markus Fritsche <mfritsche@reauktion.de> Thu, 23 Jul 2026 18:00:00 +0000
sicd (0.2.0-1) unstable; urgency=low
* Nested targets + v2 argv-boundary wire. `sic host/hop1/hop2 cmd` peels
incus/docker/pct container hops; argv is length-framed end to end so
`sic host touch 'a b'` stays ONE file (no space-split anywhere). The
daemon dual-reads v1 and v2 (first-byte dispatch), so pre-0.2.0 clients
keep working during rollout. Hardened: outer-netstring length cap before
alloc, per-element/byte caps, explicit argc (empty "" args representable,
canonical decimal only). Reviewed (bullpen 964/970).
-- Markus Fritsche <mfritsche@reauktion.de> Thu, 23 Jul 2026 12:00:00 +0000
sicd (0.1.0-1) unstable; urgency=low
* Initial release: netstring-framed argv over stdin, execvp'd. Deploy on
target hosts, run over ssh.
-- Markus Fritsche <mfritsche@reauktion.de> Sat, 19 Jul 2026 12:00:00 +0000
+19
View File
@@ -0,0 +1,19 @@
Source: sicd
Section: net
Priority: optional
Maintainer: Markus Fritsche <mfritsche@reauktion.de>
Build-Depends: debhelper-compat (= 13), golang-go
Standards-Version: 4.6.2
Homepage: https://git.reauktion.de/marfrit/sic
Package: sicd
Architecture: any
Depends: ${misc:Depends}
Recommends: openssh-server
Description: sic daemon — netstring-framed argv over stdin, execvp'd
sicd reads netstring-framed argv from stdin and runs it with execvp, so no
shell re-parses the arguments. Deploy it on target hosts and run it over ssh
(as the remote command, or pinned to a key with command="sicd").
.
Installs /usr/bin/sicd. A Python reference implementation and the wire-format
design doc are under /usr/share/doc/sicd/.
+26
View File
@@ -0,0 +1,26 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: sic
Source: https://git.reauktion.de/marfrit/sic
Files: *
Copyright: 2026 marfrit
License: MIT
License: MIT
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
.
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.