<feed xmlns='http://www.w3.org/2005/Atom'>
<title>meshbay.git/packaging/deb, branch 0.15</title>
<subtitle>MeshBay — read-only public mirror</subtitle>
<id>https://git.meshbay.org/meshbay.git/atom?h=0.15</id>
<link rel='self' href='https://git.meshbay.org/meshbay.git/atom?h=0.15'/>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/'/>
<updated>2026-09-18T12:37:08Z</updated>
<entry>
<title>feat: decode and re-encode video on the GPU where there is one</title>
<updated>2026-09-18T12:37:08Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-09-18T12:37:08Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=d22ce0ba5aebfff5ffaea97982472f876af5da22'/>
<id>urn:sha1:d22ce0ba5aebfff5ffaea97982472f876af5da22</id>
<content type='text'>
A 1080p film is decoded by whoever watches it and re-encoded by the node
when no browser can decode the source. Both were on the CPU, and on an
Atom or Celeron mini-PC neither reaches real time — which is what
`transcode_incompatible_video` exists to refuse. This adds the mechanism
that makes refusing it unnecessary.

Node — `hwaccel.py`: VA-API on Linux, Quick Sync or NVENC on Windows,
established by encoding 1080p and reading the file back with ffprobe.
Nothing is accepted that does not produce the exact profile and level
`stream_init` announces, since the client checks that string before it
trusts a byte: an encoder that wrote another level would make the node's
own codec string a lie, and ffmpeg takes `-level 4.1` and `-level 41`
from h264_qsv without saying which it understood. Three modes per
stream — hardware decode and encode, hardware encode alone, libx264 —
demoted per source codec, because a GPU that decodes HEVC may have no
decoder for MPEG-4 Part 2 and only asking it finds out. A mode that
fails is detected on an empty stdout before `stream_init` goes out, so
the viewer sees one working stream and never an error.

Client — Chromium ships VA-API off on Linux. It is enabled where a
render node and a driver are present, then verified through
`navigator.mediaCapabilities`: a no moves to the next GL backend on the
next launch and an exhausted list drops the switches, so a renamed
feature cannot pass for a feature that is on and `--ignore-gpu-blocklist`
cannot survive on a machine it did not help. Feature lists now merge
rather than overwrite — `appendSwitch` replaces the value, and a second
caller would have silently cancelled the mDNS switch aiortc depends on.

Packaging — the drivers are weak dependencies on all four formats, so a
machine without a GPU installs exactly as before. `dpkg -i` and
`rpm -ivh` ignore weak deps; `packaging/README.md` now says so. Windows
needs no driver: the bundled ffmpeg already carries h264_qsv and
h264_nvenc, and a re-pin that dropped them would cost every low-power
Windows node its hardware encoding silently.

AMD on Windows (AMF) and macOS (VideoToolbox) are named gaps, not
oversights: neither could be tried anywhere in this project, and both
re-encode in software as before.

Co-Authored-By: Claude Opus 5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Update spec contact to devel@meshbay.org</title>
<updated>2026-09-14T13:20:48Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-09-14T13:20:48Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=c33286acacf647fddef7ad8e167fd1e2a98ea3a9'/>
<id>urn:sha1:c33286acacf647fddef7ad8e167fd1e2a98ea3a9</id>
<content type='text'>
</content>
</entry>
<entry>
<title>fix(packaging): the hub unit can start, and nothing carries the migration path</title>
<updated>2026-09-12T14:36:54Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-09-12T14:15:16Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=c5fff4ce8366b08669c0c8b6d30b99b94b9fefca'/>
<id>urn:sha1:c5fff4ce8366b08669c0c8b6d30b99b94b9fefca</id>
<content type='text'>
`ExecStartPre` ran `alembic -c /opt/meshbay-hub/migrations/alembic.ini upgrade
head`. The build does stage that file, so the path existed and the contents
were wrong: `alembic.ini` resolves `script_location` with `%(here)s`, so the
copy pointed at `/opt/meshbay-hub/migrations/src/meshbay_hub/db/migrations` —
which nothing installs, because the migrations ship inside `meshbay_hub`, in
the shared venv.

`ExecStartPre` failing stops the unit. A hub installed from the RPM or the DEB
could not start at all, and nothing noticed because the one live deployment
was assembled by hand — the same shape as the node unit that carried `User=`
into the user unit directory.

The same `%(here)s` trap was already found once on the server, where a stray
`alembic.ini` resolved to a month-old snapshot of the tree. Twice is a trap
rather than an accident, so the fix is that the path is no longer written down
anywhere: `meshbay-hub migrate` asks the installed package where its own
migrations are, which is correct for the RPM, the DEB, a venv and a checkout.
The build stages no `alembic.ini`; the repo keeps its own for `alembic
revision` and for deploy scripts that already work.

`env.py` now prefers a URL the caller resolved over re-reading the environment
itself, so `migrate --config` connects with exactly the string the server
will — one resolution, not two that agree until they do not.

Six tests, three of which fail against the unit as it was. They read the
directives rather than the file, because searching the whole thing finds the
comment explaining a directive and calls that the directive.

Co-Authored-By: Claude Opus 5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01T4YmK41VsEURWFdop4EEeT
</content>
</entry>
<entry>
<title>fix(packaging): ship the example hub config, and stop leaving /etc/meshbay open</title>
<updated>2026-09-02T09:22:23Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-09-02T09:22:23Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=19a7201d1d911c9f25bc112a3e0d2218eb6c14a2'/>
<id>urn:sha1:19a7201d1d911c9f25bc112a3e0d2218eb6c14a2</id>
<content type='text'>
Three defects, found while answering whether installing the .deb would land
where the production server was just moved to by hand.

- **The example config was never packaged.** `build-hub.sh` copied
  `packaging/conf/hub.toml.example` under `if [ -f ]`, and that path does not
  exist in this repo — so every package ever built shipped no example at all
  and said nothing about it. The postinst places no config either, on purpose
  (a shipped hub.toml is overwritten on upgrade; a shipped secret gets run in
  production), which left an installed hub with nothing to copy from. The file
  now exists, documents every key `config.py` reads including the captcha
  `allowed_hosts` the desktop client needs, and the copy is a hard failure
  rather than a silent skip.

- **`/etc/meshbay` was created 0755.** It holds the hub's Ed25519 private key
  and its database password. The file modes protect the contents, but a
  world-listable config directory tells anyone with a shell what a hub keeps
  and where. Now 0750 root:meshbay, in both the deb postinst and the rpm
  scriptlet; the service reads it by group.

- **The rpm would have failed to build on the new file.** `%files` claimed
  nothing under /etc, and rpmbuild refuses an installed file no line claims.
  It now declares the directory and the example, with explicit `%attr` and
  `%config` so an operator's edits become .rpmsave rather than vanishing.

Package modes no longer follow the builder's umask either — the same source
tree produced 775/664 on a machine with umask 002 and 755/644 with 022.
`install -m` sets them.

Verified by building: the deb now carries ./etc/meshbay/ at drwxr-x--- with
hub.toml.example at 0644, and the embedded postinst tightens the directory as
belt and braces rather than as the only thing making it right. The rpm path is
unverified — no rpmbuild on this machine.

Co-Authored-By: Claude Opus 5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_014UtzVrzM7e2tG9fSpkR9ML
</content>
</entry>
<entry>
<title>chore(packaging): drop orphaned python3-meshbay-common deb control</title>
<updated>2026-09-01T13:51:25Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-09-01T13:51:25Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=854a9441ccb734c7fbb1e0ff8570b9ef659c09b0'/>
<id>urn:sha1:854a9441ccb734c7fbb1e0ff8570b9ef659c09b0</id>
<content type='text'>
The directory held a single DEBIAN/control still pinned to 0.2.0. Nothing
builds it: build-packages.sh packages meshbay-common (the bundled-venv
deb under packaging/deb/meshbay-common/), which replaced the old
system-Python python3-meshbay-common package.

Co-Authored-By: Claude Sonnet 5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01QNPfgH6VWcRzJDZGuzy1jJ
</content>
</entry>
<entry>
<title>refactor(node): JSON-only control API, Node page absorbs the admin dashboard</title>
<updated>2026-09-01T12:08:32Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-09-01T12:08:32Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=cfc91e0a424163869c64d30e55d55a53f18a3dbf'/>
<id>urn:sha1:cfc91e0a424163869c64d30e55d55a53f18a3dbf</id>
<content type='text'>
Remove the node daemon's server-rendered admin UI (GET / and /audit, the
_render_* helpers and inline templates) and the `meshbay-node ui` CLI verb.
The loopback control API stays; it is now JSON only, ruff-clean, and 453
lines (was 1074). Also drop three never-wired endpoints (/api/config,
/api/chat/history, /ws/chat, plus broadcast_chat) and the pointless
18000/tcp firewall profiles.

The desktop client's Node page (static/node-page.js) takes over what the
dashboard showed, reorganised into six tabs (Overview, Groups, Roster,
Peers, Audit, Settings):
- Overview: version, node id, QUIC port, hub, index-cache maintenance
- Roster: node-wide view with unpin
- Peers and Audit: auto-load on open, no Load button
- Audit: real usernames and group names (resolved from the roster and
  node.toml), Previous/Next pagination newest-first, Export CSV of every
  matching row
- Settings: node settings, STUN, ICE, denylist, then Unlink from hub

Backend: audit.get_entries gains `offset`; /api/audit and /api/peers
resolve ids to names via a new _display_names helper; CSP tightened to
default-src 'none' now that no HTML is served. draft-v6 sections 2.11 and
2.12 corrected -- the Node page uses the loopback API, not MNP.

One capability is intentionally dropped: browser-based admin on a headless
server. The CLI covers every operation there.

See docs/refactor-node-ui.md.

Co-Authored-By: Claude Sonnet 5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01MQCaZnde4Bjjdu84dhSuF5
</content>
</entry>
<entry>
<title>feat(packaging): 4-package .deb/.rpm build system under /opt</title>
<updated>2026-08-31T08:49:45Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-08-31T08:49:45Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=8d5c564e75ad2928e77ea66decc979366ca5ccd5'/>
<id>urn:sha1:8d5c564e75ad2928e77ea66decc979366ca5ccd5</id>
<content type='text'>
Shared venv architecture: meshbay-common owns the Python venv with all
pip deps pre-installed; hub and node add only their code into it.
Client is a standalone Electron app. No pip runs at install time.

- Add build scripts (packaging/build/) for common, hub, node, client
- Add orchestrator build-packages.sh with deb/rpm auto-detection
- Add .deb control/postinst for all 4 packages
- Add .rpm specs for all 4 packages (replaces python3-meshbay-common)
- Add Gnome .desktop launcher and icon resizing
- Add firewalld services (meshbay-cast, meshbay-node) and UFW profiles
- Update systemd units to use /opt/meshbay-common/venv/bin/ paths
- TMDB token baked into node package at build time via QE/node.env
- Fix package-lock.json sync for protobufjs override

Co-Authored-By: Claude Opus 4.6 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>chore: release 0.2.0</title>
<updated>2026-08-14T18:54:47Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-08-14T18:54:47Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=e525f7e123b621deec10a9719efa10ccafa93ad0'/>
<id>urn:sha1:e525f7e123b621deec10a9719efa10ccafa93ad0</id>
<content type='text'>
All three packages together, as the conventions require, plus the RPM and DEB
metadata and their changelogs.

The tag said 0.2 while every package announced 0.1.0, which would have shipped an
RPM claiming to be the reviewed build while containing a different protocol: the
hub schema lost the user identity keys, tokens lost pk_user, and
gek_bundle_store left the wire. Pre-1.0, a breaking change bumps MINOR.

Co-Authored-By: Claude Opus 5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>chore: add RPM/DEB packaging artifacts — 5.10</title>
<updated>2026-08-09T03:19:13Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-08-09T03:19:13Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=deee67755991994742ef144400857dd5f6b8aafa'/>
<id>urn:sha1:deee67755991994742ef144400857dd5f6b8aafa</id>
<content type='text'>
3 packages: python3-meshbay-common (dep), meshbay-hub, meshbay-node.
RPM: spec files with pre/post scriptlets (useradd, systemd macros).
DEB: DEBIAN/control + postinst for hub, control for node + common.
Systemd: hub.service (system, security hardening) + node.service
(user template @%i, EnvironmentFile for MESHBAY_UNLOCK_KEY).
packaging/README.md: build + install instructions.

Co-Authored-By: Claude Sonnet 4.6 (1M context) &lt;noreply@anthropic.com&gt;
</content>
</entry>
</feed>
