feat(bus): host-local UNIX-socket pub/sub worker (DEBT-029)

Land the `decnet bus` worker and `get_bus()` factory. Transport is a
host-local UNIX-domain socket (0660, group=decnet); authz is the file
mode. Wire framing is a tiny verb-line + 4-byte-BE length + orjson body.
NATS-style wildcard topics (`*`, `>`). At-most-once, fire-and-forget —
DB stays the source of truth. `FakeBus` / `NullBus` for tests and the
disabled path. Cross-host federation is deferred to a future
`--bridge-tcp` mode; DEBT-030 is master-only and unblocked.
This commit is contained in:
2026-04-21 13:49:02 -04:00
parent 4481a947d4
commit fbf289ff63
23 changed files with 2167 additions and 4 deletions

43
deploy/decnet-bus.service Normal file
View File

@@ -0,0 +1,43 @@
[Unit]
Description=DECNET Service Bus (host-local UNIX-socket pub/sub)
Documentation=https://github.com/4nt11/DECNET/wiki/Service-Bus
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=decnet
Group=decnet
WorkingDirectory=/opt/decnet
EnvironmentFile=-/opt/decnet/.env.local
# /run/decnet is created automatically with the RuntimeDirectory= directive
# below (mode 0755, owned by User/Group) and cleaned up on stop. The bus
# socket is placed inside it with 0660 perms so only the decnet group can
# connect.
RuntimeDirectory=decnet
RuntimeDirectoryMode=0755
ExecStart=/opt/decnet/venv/bin/decnet bus \
--socket /run/decnet/bus.sock \
--group decnet
# No privileged network operations — UNIX-domain socket only.
CapabilityBoundingSet=
AmbientCapabilities=
# Security Hardening
NoNewPrivileges=yes
ProtectSystem=full
ProtectHome=read-only
PrivateTmp=yes
ProtectKernelTunables=yes
ProtectKernelModules=yes
ProtectControlGroups=yes
RestrictSUIDSGID=yes
LockPersonality=yes
ReadWritePaths=/run/decnet /var/log/decnet
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target