bd daemon sync: 2026-01-08 17:13:57

This commit is contained in:
Dan 2026-01-08 17:13:57 -08:00
parent 3f3c59a2f9
commit 7580d1e91a

View file

@ -124,7 +124,7 @@
{"id":"ops-jrz1-p2d","title":"Add egress connection logging","description":"Log all new outbound connections for forensics.\n\n## Config\n```nix\nnetworking.firewall.extraCommands = ''\n # Log all new outbound from regular users\n iptables -A OUTPUT -m state --state NEW -m owner --uid-owner 1000:65534 \\\n -j LOG --log-prefix \"EGRESS: \" --log-level info\n'';\n```\n\n## Usage\n```bash\n# View egress logs\njournalctl -k | grep EGRESS\n\n# Watch live\njournalctl -kf | grep EGRESS\n```\n\n## Notes\n- Logs before rate limit rules (if both implemented)\n- Includes source UID, dest IP, dest port","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-02T20:17:39.566590459-08:00","created_by":"dan","updated_at":"2026-01-02T21:12:35.575052381-08:00","closed_at":"2026-01-02T21:12:35.575052381-08:00","close_reason":"Closed"} {"id":"ops-jrz1-p2d","title":"Add egress connection logging","description":"Log all new outbound connections for forensics.\n\n## Config\n```nix\nnetworking.firewall.extraCommands = ''\n # Log all new outbound from regular users\n iptables -A OUTPUT -m state --state NEW -m owner --uid-owner 1000:65534 \\\n -j LOG --log-prefix \"EGRESS: \" --log-level info\n'';\n```\n\n## Usage\n```bash\n# View egress logs\njournalctl -k | grep EGRESS\n\n# Watch live\njournalctl -kf | grep EGRESS\n```\n\n## Notes\n- Logs before rate limit rules (if both implemented)\n- Includes source UID, dest IP, dest port","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-02T20:17:39.566590459-08:00","created_by":"dan","updated_at":"2026-01-02T21:12:35.575052381-08:00","closed_at":"2026-01-02T21:12:35.575052381-08:00","close_reason":"Closed"}
{"id":"ops-jrz1-qgm","title":"Create musiclink NixOS service with buildGoModule","description":"Add systemd service for musiclink bot:\n\n1. Build Go binary with pkgs.buildGoModule from /home/dan/proj/musiclink\n2. Create systemd.services.musiclink with:\n - DynamicUser for isolation\n - StateDirectory for config\n - Hardening (ProtectSystem, ProtectHome, NoNewPrivileges)\n - After/Requires matterbridge.service\n3. Restart policy on failure\n\nAlternative: fetchFromGitHub if we push to git.clarun.xyz","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-08T12:59:08.021057917-08:00","created_by":"dan","updated_at":"2026-01-08T16:18:17.943916003-08:00","closed_at":"2026-01-08T16:18:17.943916003-08:00","close_reason":"Handed off to musiclink team. They can use Odesli API (free, no creds) or get Spotify creds themselves.","dependencies":[{"issue_id":"ops-jrz1-qgm","depends_on_id":"ops-jrz1-kpw","type":"blocks","created_at":"2026-01-08T15:56:08.088021978-08:00","created_by":"dan"}]} {"id":"ops-jrz1-qgm","title":"Create musiclink NixOS service with buildGoModule","description":"Add systemd service for musiclink bot:\n\n1. Build Go binary with pkgs.buildGoModule from /home/dan/proj/musiclink\n2. Create systemd.services.musiclink with:\n - DynamicUser for isolation\n - StateDirectory for config\n - Hardening (ProtectSystem, ProtectHome, NoNewPrivileges)\n - After/Requires matterbridge.service\n3. Restart policy on failure\n\nAlternative: fetchFromGitHub if we push to git.clarun.xyz","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-08T12:59:08.021057917-08:00","created_by":"dan","updated_at":"2026-01-08T16:18:17.943916003-08:00","closed_at":"2026-01-08T16:18:17.943916003-08:00","close_reason":"Handed off to musiclink team. They can use Odesli API (free, no creds) or get Spotify creds themselves.","dependencies":[{"issue_id":"ops-jrz1-qgm","depends_on_id":"ops-jrz1-kpw","type":"blocks","created_at":"2026-01-08T15:56:08.088021978-08:00","created_by":"dan"}]}
{"id":"ops-jrz1-qj4","title":"Evaluate bun as faster npm alternative for AI tool installs","description":"npm install -g @google/gemini-cli takes ~1 min (580 packages). Bun is much faster. Consider: (1) Add bun to system packages, (2) Update dev-add onboarding to suggest bun install -g, (3) Or pre-install popular tools system-wide.","status":"closed","priority":3,"issue_type":"task","created_at":"2026-01-03T12:26:38.457885819-08:00","created_by":"dan","updated_at":"2026-01-04T13:49:50.343836853-08:00","closed_at":"2026-01-04T13:49:50.343836853-08:00","close_reason":"Added bun to systemPackages, updated dev-add.sh to use bun in PATH and onboarding"} {"id":"ops-jrz1-qj4","title":"Evaluate bun as faster npm alternative for AI tool installs","description":"npm install -g @google/gemini-cli takes ~1 min (580 packages). Bun is much faster. Consider: (1) Add bun to system packages, (2) Update dev-add onboarding to suggest bun install -g, (3) Or pre-install popular tools system-wide.","status":"closed","priority":3,"issue_type":"task","created_at":"2026-01-03T12:26:38.457885819-08:00","created_by":"dan","updated_at":"2026-01-04T13:49:50.343836853-08:00","closed_at":"2026-01-04T13:49:50.343836853-08:00","close_reason":"Added bun to systemPackages, updated dev-add.sh to use bun in PATH and onboarding"}
{"id":"ops-jrz1-qts","title":"RFC: Seamless dev access to ops-jrz1 repo","description":"Devs on jrz1 should be able to access ops-jrz1 repo to learn and potentially contribute. Goal: minimal friction, leverage existing SSH access.\n\n## Options explored\n\n### 1. Bare repo on server (simplest)\n```\n/srv/git/ops-jrz1.git\n```\n- Devs clone via filesystem or SSH\n- Zero setup - already have access\n- \"PR\" = branch + Matrix conversation\n- No web UI\n\n### 2. Forgejo API provisioning\n- dev-add.sh creates Forgejo account + SSH key via API\n- Full web UI, real PRs\n- More setup but polished workflow\n\n### 3. Forgejo PAM auth\n- Unix users auto-authenticate to Forgejo\n- Needs password or SSH key sync\n- More complex\n\n### 4. Gitolite\n- Lightweight, reads authorized_keys directly\n- Less UI, seamless auth\n\n## Questions\n- Do we need web UI / PR workflow, or is branch + conversation enough?\n- Is this for learning (read-only) or real contribution?\n- How many devs realistically?\n\n## Recommendation\nStart with option 1 (bare repo) - zero friction, test the workflow. Graduate to option 2 if PR workflow needed.","status":"in_progress","priority":2,"issue_type":"task","created_at":"2026-01-05T18:42:23.691289101-08:00","created_by":"dan","updated_at":"2026-01-08T17:12:23.806832999-08:00"} {"id":"ops-jrz1-qts","title":"RFC: Seamless dev access to ops-jrz1 repo","description":"Devs/agents on jrz1 should be able to access git.clarun.xyz (Forgejo on same server) seamlessly. Goal: minimal friction, leverage existing SSH access.\n\n## Orch Consensus (2026-01-08)\n\nRan serial consensus with flash-or, gemini, gpt, qwen. **Unanimous recommendation: Option B (SSH keys synced to Forgejo)**.\n\n### Why Option B Wins\n\n| Criterion | Advantage |\n|-----------|-----------|\n| Attribution | Each commit/push tied to specific user (critical for agents vs humans) |\n| Security | No PATs in plaintext, keys already used for VPS access |\n| Friction | SSH \"just works\" once key is in Forgejo |\n| Hooks/CI | Forgejo's server-side hooks, protections, webhooks all work |\n\n### Options Rejected\n\n- **D (shared account)**: Loses attribution, security nightmare as project grows\n- **E (filesystem access)**: Bypasses hooks, causes permission conflicts between `git` user and Unix users\n- **C (PAM/LDAP)**: Overkill for single VPS\n- **A (HTTP+PAT)**: Token lifecycle/rotation is extra work, agents leak tokens\n\n### Implementation Plan\n\nExtend `dev-add.sh` to:\n\n1. **Create Forgejo user** via admin API (using token from sops)\n2. **Upload SSH key** to Forgejo profile\n3. **Set git identity** (`user.name`, `user.email`)\n4. **Pre-seed known_hosts** (critical for agents - prevents interactive prompt hang)\n\n```bash\n# Key additions to dev-add.sh:\n\n# 1. Create Forgejo user\ncurl -X POST \"http://localhost:3000/api/v1/admin/users\" \\\n -H \"Authorization: token $FORGEJO_TOKEN\" \\\n -d '{\"username\": \"'$USER'\", \"email\": \"'$USER'@clarun.xyz\", \"password\": \"...\", \"must_change_password\": false}'\n\n# 2. Upload SSH key\ncurl -X POST \"http://localhost:3000/api/v1/admin/users/$USER/keys\" \\\n -H \"Authorization: token $FORGEJO_TOKEN\" \\\n -d '{\"title\": \"vps-local-key\", \"key\": \"'$PUB_KEY'\"}'\n\n# 3. Git identity\nsu - \"$USER\" -c \"git config --global user.name '$USER'\"\nsu - \"$USER\" -c \"git config --global user.email '$USER@clarun.xyz'\"\n\n# 4. Pre-seed known_hosts (prevents agent hang on first git operation)\nsu - \"$USER\" -c \"ssh-keyscan localhost \u003e\u003e ~/.ssh/known_hosts 2\u003e/dev/null\"\nsu - \"$USER\" -c \"ssh-keyscan git.clarun.xyz \u003e\u003e ~/.ssh/known_hosts 2\u003e/dev/null\"\n```\n\n### Optional Add-on\n\nOption F (anonymous reads) can supplement B for public repos - useful for \"clone without setup\" but doesn't solve writes.\n\n### Implementation Considerations\n\n- Make idempotent (don't fail if user/key already exists)\n- Handle `dev-remove.sh` cleanup (delete Forgejo user too)\n- Forgejo API token available in sops: `forgejo-api-token`\n- Consider retroactive sync script for existing users\n","status":"in_progress","priority":2,"issue_type":"task","created_at":"2026-01-05T18:42:23.691289101-08:00","created_by":"dan","updated_at":"2026-01-08T17:13:57.175825106-08:00"}
{"id":"ops-jrz1-qxr","title":"mautrix-slack message edit panic (upstream bug)","description":"Bridge upgraded to v25.11. Need to verify if edit panic is fixed by testing a Slack message edit. Watch logs: journalctl -u mautrix-slack -f | grep -E 'ERR|panic|edit'","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-12-05T18:22:38.18203834-08:00","updated_at":"2025-12-05T19:36:00.556011621-08:00","closed_at":"2025-12-05T19:36:00.556011621-08:00","dependencies":[{"issue_id":"ops-jrz1-qxr","depends_on_id":"ops-jrz1-03o","type":"blocks","created_at":"2025-12-05T18:24:23.259399275-08:00","created_by":"daemon","metadata":"{}"}]} {"id":"ops-jrz1-qxr","title":"mautrix-slack message edit panic (upstream bug)","description":"Bridge upgraded to v25.11. Need to verify if edit panic is fixed by testing a Slack message edit. Watch logs: journalctl -u mautrix-slack -f | grep -E 'ERR|panic|edit'","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-12-05T18:22:38.18203834-08:00","updated_at":"2025-12-05T19:36:00.556011621-08:00","closed_at":"2025-12-05T19:36:00.556011621-08:00","dependencies":[{"issue_id":"ops-jrz1-qxr","depends_on_id":"ops-jrz1-03o","type":"blocks","created_at":"2025-12-05T18:24:23.259399275-08:00","created_by":"daemon","metadata":"{}"}]}
{"id":"ops-jrz1-rkp","title":"Add egress abuse watchdog","description":"Monitor for users hitting egress rate limits, kill if sustained.\n\n## Script: /usr/local/bin/egress-watchdog\n```bash\n#\\!/usr/bin/env bash\n# Kill users who keep hitting egress limits\nTHRESHOLD=10 # EGRESS-LIMIT hits per minute\nCOUNTFILE=\"/var/lib/egress-watchdog\"\nmkdir -p \"$COUNTFILE\"\n\n# Count recent limit hits per UID\njournalctl -k --since \"1 minute ago\" 2\u003e/dev/null | grep \"EGRESS-LIMIT\" | \\\n grep -oP 'UID=\\K[0-9]+' | sort | uniq -c | while read count uid; do\n \n user=$(getent passwd \"$uid\" | cut -d: -f1)\n [ -z \"$user\" ] \u0026\u0026 continue\n \n if [ \"$count\" -gt \"$THRESHOLD\" ]; then\n strikes=$(cat \"$COUNTFILE/$user\" 2\u003e/dev/null || echo 0)\n strikes=$((strikes + 1))\n echo \"$strikes\" \u003e \"$COUNTFILE/$user\"\n logger -t egress-watchdog \"User $user hit egress limit $count times (strike $strikes/3)\"\n \n if [ \"$strikes\" -ge 3 ]; then\n /usr/local/bin/killswitch \"$user\" \"egress abuse ($count hits)\"\n rm -f \"$COUNTFILE/$user\"\n fi\n else\n rm -f \"$COUNTFILE/$user\"\n fi\ndone\n```\n\n## Behavior\n- Runs every minute (same timer as CPU watchdog, or separate)\n- 3 consecutive minutes of \u003e10 blocked connections = kill\n- Works with egress rate limiting (ops-jrz1-cmv)\n\n## Dependencies\n- Requires ops-jrz1-cmv (egress rate limiting)\n- Requires ops-jrz1-396 (killswitch script)","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-02T20:21:09.516724064-08:00","created_by":"dan","updated_at":"2026-01-03T06:02:02.132992356-08:00","closed_at":"2026-01-03T06:02:02.132992356-08:00","close_reason":"Egress watchdog deployed and tested. Script monitors EGRESS-LIMIT kernel log entries, tracks strikes per user, kills after 3 strikes.","dependencies":[{"issue_id":"ops-jrz1-rkp","depends_on_id":"ops-jrz1-396","type":"blocks","created_at":"2026-01-02T20:21:14.314011866-08:00","created_by":"dan"},{"issue_id":"ops-jrz1-rkp","depends_on_id":"ops-jrz1-cmv","type":"blocks","created_at":"2026-01-02T20:21:14.352411765-08:00","created_by":"dan"}]} {"id":"ops-jrz1-rkp","title":"Add egress abuse watchdog","description":"Monitor for users hitting egress rate limits, kill if sustained.\n\n## Script: /usr/local/bin/egress-watchdog\n```bash\n#\\!/usr/bin/env bash\n# Kill users who keep hitting egress limits\nTHRESHOLD=10 # EGRESS-LIMIT hits per minute\nCOUNTFILE=\"/var/lib/egress-watchdog\"\nmkdir -p \"$COUNTFILE\"\n\n# Count recent limit hits per UID\njournalctl -k --since \"1 minute ago\" 2\u003e/dev/null | grep \"EGRESS-LIMIT\" | \\\n grep -oP 'UID=\\K[0-9]+' | sort | uniq -c | while read count uid; do\n \n user=$(getent passwd \"$uid\" | cut -d: -f1)\n [ -z \"$user\" ] \u0026\u0026 continue\n \n if [ \"$count\" -gt \"$THRESHOLD\" ]; then\n strikes=$(cat \"$COUNTFILE/$user\" 2\u003e/dev/null || echo 0)\n strikes=$((strikes + 1))\n echo \"$strikes\" \u003e \"$COUNTFILE/$user\"\n logger -t egress-watchdog \"User $user hit egress limit $count times (strike $strikes/3)\"\n \n if [ \"$strikes\" -ge 3 ]; then\n /usr/local/bin/killswitch \"$user\" \"egress abuse ($count hits)\"\n rm -f \"$COUNTFILE/$user\"\n fi\n else\n rm -f \"$COUNTFILE/$user\"\n fi\ndone\n```\n\n## Behavior\n- Runs every minute (same timer as CPU watchdog, or separate)\n- 3 consecutive minutes of \u003e10 blocked connections = kill\n- Works with egress rate limiting (ops-jrz1-cmv)\n\n## Dependencies\n- Requires ops-jrz1-cmv (egress rate limiting)\n- Requires ops-jrz1-396 (killswitch script)","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-02T20:21:09.516724064-08:00","created_by":"dan","updated_at":"2026-01-03T06:02:02.132992356-08:00","closed_at":"2026-01-03T06:02:02.132992356-08:00","close_reason":"Egress watchdog deployed and tested. Script monitors EGRESS-LIMIT kernel log entries, tracks strikes per user, kills after 3 strikes.","dependencies":[{"issue_id":"ops-jrz1-rkp","depends_on_id":"ops-jrz1-396","type":"blocks","created_at":"2026-01-02T20:21:14.314011866-08:00","created_by":"dan"},{"issue_id":"ops-jrz1-rkp","depends_on_id":"ops-jrz1-cmv","type":"blocks","created_at":"2026-01-02T20:21:14.352411765-08:00","created_by":"dan"}]}
{"id":"ops-jrz1-s8x","title":"Add health check endpoint for Matrix homeserver monitoring","description":"modules/dev-services.nix Matrix service has no health check for monitoring. Add nginx location for /_matrix/client/versions health probe.","status":"open","priority":4,"issue_type":"task","created_at":"2026-01-05T15:44:34.407481321-08:00","created_by":"dan","updated_at":"2026-01-05T15:44:34.407481321-08:00"} {"id":"ops-jrz1-s8x","title":"Add health check endpoint for Matrix homeserver monitoring","description":"modules/dev-services.nix Matrix service has no health check for monitoring. Add nginx location for /_matrix/client/versions health probe.","status":"open","priority":4,"issue_type":"task","created_at":"2026-01-05T15:44:34.407481321-08:00","created_by":"dan","updated_at":"2026-01-05T15:44:34.407481321-08:00"}