Commit Graph
6 Commits
Author SHA1 Message Date
jaredandClaude Opus 5.5 f8f0ca4549 discord-bridge: Discord presence into Matrix ghosts
Lint / JS (eslint) (pull_request) Successful in 10s
Lint / Shell (shellcheck) (pull_request) Successful in 11s
Lint / No Hookshot webhook IDs in README (pull_request) Successful in 6s
Lint / No secrets in webhook configs (pull_request) Successful in 6s
Lint / Landing page is rendered (matrix (pull_request) Successful in 6s
Lint / Python (ruff) (pull_request) Successful in 7s
Lint / Secret scan (gitleaks) (pull_request) Successful in 13s
Lint / Shell (shellcheck) (push) Successful in 26s
Lint / JS (eslint) (push) Successful in 18s
Lint / No Hookshot webhook IDs in README (push) Successful in 21s
Lint / No secrets in webhook configs (push) Successful in 12s
Lint / Python deps (pip-audit) (pull_request) Successful in 1m54s
Lint / Landing page is rendered (matrix (push) Successful in 17s
Lint / Python (ruff) (push) Successful in 16s
Lint / Secret scan (gitleaks) (push) Successful in 31s
Lint / Python deps (pip-audit) (push) Successful in 1m37s
mautrix-discord doesn't bridge presence. lotus_presence.py watches the Discord
server (a second gateway session on the bridge's own bot, Guilds + Presence
intents only) and sets presence and a status message on each @discord_* ghost:
online / idle / DND / offline -> online / unavailable / msc3026 busy / offline;
custom status and the first activity become the status message.

Its own appservice registration is non-exclusive on the ghost namespace, so it
can update ghosts but not create them. Synapse drops an unrefreshed user to
offline after about a minute, so live states are re-sent every 20 s; if the
service dies, ghosts go offline rather than stale. The installer generates the
credentials on the server and doesn't restart Synapse. Statuses and activities
are never logged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
2026-11-04 19:36:38 -05:00
Lotus CIandClaude Opus 5.5 d9f023762e fix(livekit): graceful restart could restart LiveKit in the middle of a call
Lint / JS (eslint) (push) Successful in 12s
Lint / Shell (shellcheck) (push) Successful in 13s
Lint / No secrets in webhook configs (push) Successful in 6s
Lint / Landing page is rendered (matrix (push) Successful in 5s
Lint / Python (ruff) (push) Successful in 6s
Lint / Secret scan (gitleaks) (push) Successful in 8s
Lint / Shell (shellcheck) (pull_request) Successful in 10s
Lint / JS (eslint) (pull_request) Successful in 8s
Lint / No secrets in webhook configs (pull_request) Successful in 5s
Lint / Python deps (pip-audit) (push) Successful in 41s
Lint / Landing page is rendered (matrix (pull_request) Successful in 4s
Lint / Python (ruff) (pull_request) Successful in 5s
Lint / Secret scan (gitleaks) (pull_request) Successful in 11s
Lint / Python deps (pip-audit) (pull_request) Successful in 56s
livekit-graceful-restart.sh decided "no active calls" by counting
established TCP connections on :7881 with `ss ... state established |
grep -c ESTAB`. Two bugs:

- With a `state` filter ss omits the State column, so `grep -c ESTAB`
  is always 0: the check never saw anything.
- :7881 is only LiveKit's ICE-TCP media fallback. Signalling is on
  :7880 and media is normally UDP.

Reproduced in a two-person call on the local stack: the old check
counted 0 and would have restarted. Now it waits while LiveKit's own
livekit_participant_total is above 0 or any signalling WebSocket on
:7880 is open, and also waits if the metrics can't be read.

The deploy hook now installs the script when it changes (it never
did, so edits to it never reached the server).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
2026-11-03 00:25:58 -05:00
jaredandClaude Opus 4.8 a06f2c662a feat(livekit-guard): enforce per-room call permissions (screenshare/camera)
Extend voice-limit-guard to enforce a per-room publish-source policy
(io.lotus.room_quality allow_screenshare/allow_camera) for ALL Matrix clients,
alongside the existing participant limit.

- At token issue, re-sign the LiveKit JWT's canPublishSources to drop forbidden
  sources (microphone always kept). Verifies our own secret signed the token
  first and fails open on mismatch, so a secret drift can never mint a token the
  SFU rejects. Limit check and source policy are independent (one's outage can't
  skip the other).
- Live (mid-call) enforcement: a background reconcile loop calls LiveKit
  UpdateParticipant to revoke a forbidden source from participants who joined
  before the policy changed -- which unpublishes their in-progress
  screenshare/camera server-side within ~3s and blocks re-publish. Only removes
  sources (never grants), preserves other permission flags, fails open, and runs
  as a daemon thread that cannot crash or block token issuance.
- Endpoint-specific room-id extraction (/get_token->room_id, /sfu/get->room) so
  a client sending both keys can't get a different room's policy applied.
- Auto-deploy the guard on LXC 151 (py_compile-gated, backup + rollback).
- Unit tests: JWT re-sign/verify + tamper, secret-mismatch, source narrowing,
  reconcile (never-grant / preserve-flags / disable-on-empty), fail-open.

Numeric bitrate/fps caps are NOT server-enforceable on an SFU (LiveKit forwards,
never transcodes) and remain a Lotus-client-cooperative setting; the
screenshare/camera permission is the hard cross-client lever.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 22:34:34 -04:00
jaredandClaude Sonnet 4.6 b9a251bd7a Integrate matrixbot into existing LXC 151 deploy hook
Lint / Shell (shellcheck) (push) Successful in 11s
Lint / JS (eslint) (push) Successful in 6s
Removed standalone matrixbot/deploy.sh — deploy is handled by the existing
webhook system. Added matrixbot/ block to deploy/lxc151-hookshot.sh: on push,
if any matrixbot/ file changed, source files are synced to /opt/matrixbot and
matrixbot.service is restarted automatically.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 16:18:10 -04:00
jaredandClaude Sonnet 4.6 735c1eb30e ci: add lint workflow, shellcheck fixes, and CI failure hookshot alert
Lint / Shell (shellcheck) (push) Has been cancelled
Lint / JS (eslint) (push) Has been cancelled
- .gitea/workflows/lint.yml: new workflow running shellcheck on .sh files
  and eslint on hookshot/ JS transform scripts
- hookshot/.eslintrc.json: declare data/result as hookshot globals
- hookshot/ci-alert.js: new Matrix hookshot transform for CI failure alerts
- hookshot/deploy.sh: fix SC2155 (split local/assign), SC2034 (remove unused var)
- systemd/livekit-clear-port.sh: fix SC2148 (invalid shebang escape)
- cinny/dev-update.sh: fix SC2115 (use ${WEB_ROOT:?} to guard rm -rf)
- deploy/lxc151-hookshot.sh: add shellcheck source=/dev/null for sourced file
- .gitignore: ignore node_modules/
- package.json + package-lock.json: eslint@8 dev dependency

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 16:25:39 -04:00
jaredandClaude Sonnet 4.6 5e936b2ca1 Add auto-deployment infrastructure for all 4 LXCs
- Per-LXC deploy scripts (lxc151-hookshot, lxc106-cinny, lxc139-landing, lxc110-draupnir)
- Per-LXC webhook hook configs with unique HMAC-SHA256 secrets
- Livekit graceful restart script + systemd timer (waits for zero active calls)
- Fix hookshot/deploy.sh capitalization bug (Uptime-Kuma, Tinker-Tickets, etc.)

Each LXC independently clones repo and runs its own deploy.sh via adnanh/webhook on port 9000.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-18 11:41:32 -04:00