Skip to content

scripts - Action Report

Project: /home/user/scripts Created: 2026-02-19


Created nexus-network-reset.sh (2026-02-19 21:40)

What: One-command network reset script that kills all proxies and restores direct internet via 192.168.1.1.

Why: User was having difficulty recovering from proxy configurations that disrupted normal internet access. Multiple proxy scripts, dead VM routes (10.152.152.1 via eth0), and accumulated podman medusa-proxy containers were creating network confusion.

How: 7-phase script: 1. Stop proxy services (Tor, Privoxy, tinyproxy, etc.) 2. Stop proxy containers (podman) 3. Flush iptables NAT/mangle tables 4. Clean routing (remove dead 10.152.152.1 route, ensure default via 192.168.1.1) 5. Reset DNS to 192.168.1.1 6. Clear proxy env vars 7. Connectivity tests (gateway, DNS, internet, full HTTPS chain)

Files: /home/user/scripts/nexus-network-reset.sh Dependencies: doas or sudo for iptables/route changes


Created nexus-medusa.sh - Complete proxy launcher (2026-02-19 21:41)

What: Full-featured Tor proxy launcher and manager with 20+ commands.

Why: User was running medusa-proxy via raw podman aliases, leading to 13+ orphaned containers, port conflicts, and no management tooling.

Features (1736 lines): - 3 quick-pick profiles (World/US/No-Eyes) on non-conflicting ports - Custom mode with configurable heads, circuits, countries, ports - Paranoid mode (iptables + env vars route ALL traffic through proxy) - Kill switch (blocks all traffic if proxy container goes down) - Live monitor with keybinds (rotate circuits, test IPs, stats) - New circuit button (SIGHUP like Tor Browser) - Bridge seeding (paste, file import) - FascistFirewall toggle for restrictive networks - Snowflake proxy (ON by default - help censored users) - Middle relay (opt-in Tor relay) - Proxychains-ng integration with multi-profile chaining - Network namespace boxes (kernel-level leak-proof isolation) - De-anonymization scan (services, IPv6, DNS, MAC, hostname, timezone, WebRTC) - PAC file generation (smart routing: local/Yggdrasil/i2p direct, rest through proxy) - Profile save/load system - --json output on all commands (Phase 2 GUI ready) - Container auto-destruction on stop (no more name collisions)

Port Architecture: | Profile | SOCKS | HTTP | Stats | |---------|-------|------|-------| | World | 1080-1082 | 8888-8890 | 2090-2092 | | US | 1180-1182 | 9888-9890 | 2190-2192 | | No-Eyes | 1280-1282 | 7888-7890 | 2290-2292 |

Files: - /home/user/scripts/nexus-medusa.sh - /home/user/scripts/nexus-medusa.help.md (5th-grade-friendly manual) - .zshrc updated with 7 aliases

Dependencies: podman, proxychains-ng (optional), snowflake-proxy (optional)


Created nexus-report.sh - Project report system (2026-02-19 21:41)

What: Automated reporting system with project-specific reports and central symlink hub.

Why: Docs, reports, and manuals were spread across 6+ locations with no standard structure. 45 projects, 63 git repos, 102 scripts, 61 manuals - all unlinked. Previous session's organization work was lost when credits ran out.

Protocol established: - Write detailed reports PER TASK (not end of session) while context is fresh - Every project gets docs/action_report.md - Central hub at ~/claude/reports/ with symlinks to each project report - Master report at ~/claude/action_report.md gets one-line summaries with links

Commands: - nexus-report.sh <path> <title> <body> - Append task report to project - nexus-report.sh --init <path> - Initialize docs/ for a project - nexus-report.sh --list - Show all project reports with entry counts - nexus-report.sh --scan - Find and symlink existing project reports

Files: /home/user/scripts/nexus-report.sh


Fixed greetd login manager + added NeXuS terminal sessions (2026-02-21)

What: Diagnosed greetd crash, fixed config, removed tor autostart, added two new beautiful terminal sessions to the NeXuS login screen.

Why: greetd was crashing on boot because /etc/inittab had a getty respawning on tty1 (conflicting with greetd owning VT1), and the session-wrapper path used ~ which doesn't expand for the system greeter user (no home dir). User also wanted tor removed from startup and a way to get back the beautiful terminal experience previously seen via slim.

Root Causes Fixed:

  1. greetd crash — /etc/inittab tty1::respawn:getty fought greetd for VT1. Fix: apply.sh now comments out the tty1 getty line.
  2. ~ in config.toml — --session-wrapper '~/.local/bin/sway-session-wrapper' resolved to wrong path for greeter system user. Fix: changed to absolute /home/user/.local/bin/sway-session-wrapper.
  3. slim conflict — slim was still running alongside greetd. Fix: apply.sh now stops and disables slim too.
  4. tor autostart — removed from default runlevel via apply.sh.

Keyboard mystery solved: When slim (X11 DM) launched the CLI session (Exec=/bin/zsh -l), it ran zsh inside X11 with no terminal window — keyboard events went to X's focused client (nothing). The beautiful terminal seen was xfce4-terminal from the xinitrc fallback list, not foot (foot is Wayland-only and cannot run under X11).

New sessions added to /usr/share/wayland-sessions/:

Session Command Description
NeXuS Terminal cage -- foot Wayland kiosk compositor + foot (Tokyo Night, JetBrains Mono Nerd)
NeXuS Console kmscon --font-name "JetBrains Mono" ... -l -- /bin/zsh -l GPU-rendered terminal, no compositor at all

Files changed: - /home/user/greetd-setup/etc/greetd/config.toml — fixed ~ → absolute path - /home/user/greetd-setup/apply.sh — added: comment tty1 getty, disable slim, remove tor, install both new sessions - /home/user/greetd-setup/sessions/nexus-terminal.desktop — new (cage+foot) - /home/user/greetd-setup/sessions/nexus-console.desktop — new (kmscon+zsh)

Run: doas sh ~/greetd-setup/apply.sh then reboot.

Session menu after reboot:

NeXuS Console   ← kmscon, GPU fonts, no compositor
NeXuS Terminal  ← cage + foot, full Wayland
sway            ← full DE
CLI             ← raw zsh fallback


Created nexus-wifi.sh (2026-02-21 23:57)

What: WiFi network switcher script using nmcli + fzf. Why: Quick CLI-first way to scan and switch WiFi networks. How: Wraps nmcli for NetworkManager; fzf for interactive selection; handles saved profiles, new networks (password prompt), and rescan. Files: ~/scripts/nexus-wifi.sh


Wiki fixed + River greetd integration (2026-02-23 09:40)

What: Fixed broken wiki auto-import daemon, verified 422 docs live in nb, restarted daemon with correct code. Added River compositor to greetd login manager with fixed init script.

Why: Wiki was storing file paths instead of content (nb add bug). River init had broken/missing config - picom/pulseaudio not installed, recursive river call, no keybindings, wrong keyboard layout command.

How: - Wiki: Killed old daemon (PID 713) running broken nb add code. Restarted wiki_auto_import.sh with nb import fix from last session. Bulk import already completed - 422 docs across 4 notebooks (manuals:173, nexus-docs:130, ai-projects:107, home:12). socat server confirmed running at localhost:6789. - River: Backed up ~/.config/river/init. Rewrote init with: correct riverctl keyboard-layout us, removed picom (X11 only/not installed), removed pulseaudio (not installed/system uses PipeWire), removed recursive river call at end, added full riverctl map keybindings (Super+Return/D/Q/F/Space/H/L/J/K/Shift+E/Ctrl+L), added workspace switching 1-9, added rivertile layout engine, Tokyo Night border colors, wallpaper fallback to existing cache. - greetd: Created ~/greetd-setup/sessions/river.desktop staged for install. Needs: doas cp ~/greetd-setup/sessions/river.desktop /usr/share/wayland-sessions/river.desktop

Files: - ~/.config/river/init - rewritten (backup: init.bak.20260223_*) - ~/greetd-setup/sessions/river.desktop - NEW - Wiki daemon restarted with fixed code

Pending: - Run: doas cp ~/greetd-setup/sessions/river.desktop /usr/share/wayland-sessions/river.desktop - nexus-nb-publish.sh - content scrubber + git pre-push hook for safe GitHub sync (designed, not yet built) - wiki_sync.sh still uses broken nb add (low priority - auto-import daemon handles it now)


labwc-apps-menu.sh + nexus-wallpaper-pick.sh (2026-02-27 13:41)

What: Two new scripts for the labwc right-click menu.

labwc-apps-menu.sh - Reads all .desktop files from /usr/share/applications and ~/.local/share/applications - Skips NoDisplay=true entries - Wraps Terminal=true apps in foot -e - Groups by category (AudioVideo→Sound & Video, Network→Internet, etc.) - Sorts alphabetically within each category - Outputs labwc-compatible XML for use as a pipe menu (execute= attribute) - Usage: called automatically by labwc when Applications submenu is opened

nexus-wallpaper-pick.sh - Searches ~/Pictures, /usr/share/lxqt/wallpapers, /usr/share/wallpapers, /usr/share/pixmaps for image files - Presents list via fuzzel --dmenu - Passes chosen file to nexus-theme.sh (sets wallpaper + regenerates all themes) - Silently exits if user cancels

Files: - ~/scripts/labwc-apps-menu.sh (new, chmod +x) - ~/scripts/nexus-wallpaper-pick.sh (new, chmod +x)

Dependencies: fuzzel (dmenu mode), nexus-theme.sh, swaybg


Fixed nexus-medusa.sh -- podman --replace flag (2026-03-07 18:05)

What: Added --replace flag to both podman run calls in nexus-medusa.sh to prevent "name already in use" container conflicts.

Why: When Medusa tried to launch a container with a name that already existed (stopped, crashed, or orphaned), Podman would error with "that name is already used". The script had manual cleanup code (podman stop + podman rm -f) above the run call but race conditions or partial failures could still leave the name occupied.

How: Added --replace to both podman run invocations:

Line 190 — main container launch: ```bash

Before:

cid=$(podman run -d --rm --name "$name" \

After:

cid=$(podman run -d --rm --replace --name "$name" \ ```

Line 789 — relay container launch: ```bash

Before:

podman run -d --rm --name "$relay_name" \

After:

podman run -d --rm --replace --name "$relay_name" \ ```

--replace atomically stops and removes any existing container with the same name before creating the new one. The existing manual cleanup code above line 190 was left intact — no features removed.

Files: - /home/user/scripts/nexus-medusa.sh — patched - /home/user/scripts/nexus-medusa.sh.bak.* — timestamped backup


Fixed nexus-medusa.sh: added --replace to podman run calls (2026-03-07 22:03)

What: Added --replace flag to both podman run calls in nexus-medusa.sh to fix 'container name already in use' error on restart.

Why: When Medusa restarts or re-spawns a container with a name that already exists (e.g. after a crash or manual stop), podman errors with 'name already in use'. --replace atomically removes the old container and starts fresh.

How: Two lines changed — no features removed, no logic altered: - Line ~190: podman run -d --rm --replace --name "$name" ... - Line ~789: podman run -d --rm --replace --name "$relay_name" ...

Files: - /home/user/scripts/nexus-medusa.sh (2 lines modified)

Dependencies: podman, nexus/medusa-proxy image


Fix nexus-wifi.sh — invalid field + hardcoded wlan0 + fzf ioctl (2026-03-09 19:07)

What: Fixed three bugs in nexus-wifi.sh causing 'invalid field 802-11-wireless.ssid', 'Connection activation failed', and 'inappropriate ioctl for device' errors.

Why: Script was broken — SSID lookup used an invalid nmcli list field, disconnect hardcoded wlan0, and fzf reload bind caused ioctl error on Alpine.

How: 1. invalid field fix: switched from list-mode field to per-profile query — nmcli connection show called per profile to read 802-11-wireless.ssid 2. wlan0 fix: detect active WiFi device dynamically via nmcli device status 3. ioctl fix: removed sleep from fzf ctrl-r reload bind (BusyBox ioctl issue in that context)

Files: nexus-wifi.sh (backed up to nexus-wifi.sh.bak.TIMESTAMP)


Fixed nexus-wifi.sh — 3 bugs resolved (2026-03-09 19:37)

What: Fixed nexus-wifi.sh WiFi switcher script — was throwing 'invalid field' and 'invalid parameter' errors making it non-functional.

Why: Script had 3 distinct bugs that prevented connecting to saved networks and disconnecting from WiFi.

How:

Bug 1 — nmcli invalid field error: - Problem: nmcli -t -f NAME,802-11-wireless.ssid connection show throws 'Error: invalid field 802-11-wireless.ssid' because 802-11-wireless.ssid is not a valid list-mode field, only a per-profile field - Fix: Changed connect_to() to loop through saved profiles individually, querying each with nmcli connection show <profile> to read 802-11-wireless.ssid per-profile, then match against the target SSID

Bug 2 — hardcoded wlan0 device name: - Problem: --disconnect flag had local wifi_dev declared inside a case block (invalid in bash) and hardcoded 'wlan0' which fails on systems with different interface names (wlp2s0, wlan1, etc.) - Fix: Detect device dynamically: nmcli -t -f DEVICE,TYPE device status | grep ':wifi:' | cut -d: -f1 | head -1

Bug 3 — fzf reload bind ioctl error: - Problem: --bind ctrl-r:reload(...) had a sleep 2 inside the reload command. fzf executes reload commands in a subshell with no TTY, so sleep throws 'Inappropriate ioctl for device' - Fix: Removed sleep from the fzf reload bind entirely (rescan itself takes a moment anyway)

Files: /home/user/scripts/nexus-wifi.sh

Dependencies: nmcli, fzf


Fix UFW+PSAD logging chain (klogd missing) (2026-03-09 21:55)

What: Fixed broken logging chain preventing PSAD from ever detecting port scans.

Why: PSAD was running for months but had never detected a single packet. Three separate failures in the chain made it completely blind.

Root Causes Found (in order of investigation): 1. klogd not running — iptables LOG entries go to kernel ring buffer only. Without klogd reading /proc/kmsg and forwarding to syslogd, firewall events never reach /var/log/messages. klogd was installed but stopped, not in any runlevel. 2. before.rules LOG rules had no --log-prefix — even if klogd ran, PSAD couldn't identify firewall entries vs other kernel messages. Rules were: -A INPUT -j LOG (all traffic, no prefix, wrong chain). 3. psad.conf SYSLOG_DAEMON set to 'metalog' — but metalog is not running. Busybox syslogd (/sbin/syslogd) is the actual daemon. 4. metalog.conf had a syntax error in the fail2ban section (missing closing quote on logdir line) — not actively harmful since metalog is not running, but fixed for correctness.

How: - Diagnosed by: checking lsmod (ip_tables 0 refs, xt_LOG 22 refs = rules loaded but logs going nowhere), checking ps (no klogd), checking /var/log/messages (no kern.* entries at all), checking rc-status (syslog = busybox syslogd). - Fix script created: ~/scripts/nexus-fix-psad-logging.sh (run with: doas sh ~/scripts/nexus-fix-psad-logging.sh)

Files: - ~/scripts/nexus-fix-psad-logging.sh — fix script (backups, all 4 fixes, service restarts) - /etc/ufw/before.rules — LOG rules get [UFW BLOCK] prefix + moved to ufw-before-input chain - /etc/psad/psad.conf — SYSLOG_DAEMON changed to syslogd, IPT_PREFIX=[UFW BLOCK] added - /etc/metalog.conf — fail2ban logdir syntax error fixed - /etc/conf.d/klogd — klogd added to boot runlevel

To apply: doas sh ~/scripts/nexus-fix-psad-logging.sh To verify: grep 'UFW BLOCK' /var/log/messages && psad --Status


Fix fwsnort iptables-nft port negation incompatibility (2026-03-09 22:20)

What: Fixed fwsnort failing to load 29,680 rules due to 8 lines with invalid iptables-nft port negation syntax.

Why: iptables-restore v1.8.11 (nf_tables) rejects rules where ! appears inside a multiport comma-separated list (e.g. --dports 25,!445,!1500). This caused the entire fwsnort ruleset to fail at line 19885, leaving zero snort-based detection active.

Root cause: fwsnort incorrectly translates some Snort port negation rules into multiport lists with ! inside the values. This is a fwsnort translation bug - the syntax was tolerated by legacy iptables but rejected by nftables backend.

How: Identified 8 bad command lines out of 29,680 total (grep 'dports.*,![0-9]'). Strip those lines with sed before applying rules. The 8 removed rules represent untranslatable signatures - removing them is safer than corrupting the match logic.

Files created: - ~/scripts/nexus-fix-fwsnort-nftables.sh — strips 8 bad lines, re-applies rules via fwsnort_iptcmds.sh (individual iptables calls, not restore), signals PSAD - ~/scripts/nexus-update-fwsnort.sh — full replacement for /usr/bin/update-fwsnort, includes fix step

To apply now: doas sh ~/scripts/nexus-fix-fwsnort-nftables.sh To make permanent: doas cp ~/scripts/nexus-update-fwsnort.sh /usr/bin/update-fwsnort To verify: doas iptables -L | grep FWSNORT (should show fwsnort chains)


Created PSAD and fwsnort manuals (2026-03-09 22:35)

What: Wrote comprehensive manuals for PSAD and fwsnort covering this system's specific configuration, all scripts, FAQs, and troubleshooting.

Files created: - ~/scripts/docs/PSAD_MANUAL.md — full PSAD manual with config reference, daily ops, troubleshooting, FAQ, links to nexus-fix-psad-logging.sh - ~/scripts/docs/FWSNORT_MANUAL.md — full fwsnort manual with nft compat issue documented, update workflow, troubleshooting, FAQ, links to nexus-fix-fwsnort-nftables.sh and nexus-update-fwsnort.sh

Covers: detection chains, danger levels, all commands, script descriptions, key files, how PSAD+fwsnort work together


Fix fail2ban logpath — watching empty file (2026-03-09 23:04)

What: Fixed fail2ban watching /var/log/sshd_log (empty since Jan 2025) instead of /var/log/messages where SSH actually logs.

Why: fail2ban was running but could never ban anyone. The correct logpath was already commented in the config — someone knew the fix but left it inactive.

Root cause: Alpine with busybox syslogd routes auth.* facility to /var/log/messages. fail2ban's paths-common.conf defaults sshd_log to /var/log/auth.log which does not exist. The jail.d override was pointing to /var/log/sshd_log which is also empty.

Also confirmed: PermitRootLogin no already set in /etc/ssh/sshd_config — root SSH login already disabled.

How: Fix logpath in jail.d/alpine-ssh.conf + create paths-overrides.local for Alpine-correct global default. Also tightened maxretry from 10 to 5.

Files: - ~/scripts/nexus-fix-fail2ban.sh — fix script - /etc/fail2ban/jail.d/alpine-ssh.conf — logpath fixed - /etc/fail2ban/paths-overrides.local — Alpine syslog path override

To apply: doas sh ~/scripts/nexus-fix-fail2ban.sh To verify: doas fail2ban-client status sshd


NeXuS Notes — tmux-menus popup notes system (2026-03-10 00:02)

What: Built a full CLI notes system integrated into the tmux-menus popup (F12 |).

Why: User wanted a quick-access notes option accessible from within their existing tmux popup workflow without leaving the terminal.

How:

  1. Created nexus-notes.sh — main notes manager
  2. browse_notes(): fzf file picker with live glow-rendered markdown preview (right:55% pane)
  3. new_note(): prompts for title via plain read, slugifies to filename, creates dated .md template, opens at line 6 in micro (cursor lands below the --- separator ready to write)
  4. quick_note(): one-liner append to quick-notes.md with timestamp
  5. main_menu(): simple [b/n/q/x] menu for direct launch
  6. Editor priority: micro → nano → vim
  7. Storage: ~/notes/nexus/*.md

  8. Created wrapper scripts (required because tmux-menus E-type entries use run-shell which cannot embed complex tmux commands inline):

  9. nexus-notes-browse.sh: tmux display-popup -E -h 85% -w 80%
  10. nexus-notes-new.sh: tmux display-popup -E -h 85% -w 80%
  11. nexus-notes-quick.sh: tmux display-popup -E -h 20% -w 60%

  12. Created tmux-menus item: ~/.tmux/plugins/tmux-menus/items/nexus_notes.sh

  13. Menu entries: Browse notes, New note, Quick one-liner, Open notes folder
  14. Each E-type entry calls the appropriate wrapper script

  15. Added to main.sh: inserted NeXuS Notes entry after Extras in the main menu

  16. Key: Z, label: NeXuS Notes → (nav_next arrow)

Troubleshooting encountered and resolved: - display-popup inside display-popup fails silently (tmux limitation) — solved by using wrapper scripts called via run-shell - tmux-menus E-type with inline display-popup command caused 'not enough arguments' error — solved by wrapper scripts - micro cursor opens at line 1 (title) requiring manual scroll — solved with micro +6 to open at writing position - Tried tmux command-prompt for title input — caused popup to close — reverted to plain read

Files: - ~/scripts/nexus-notes.sh — main notes script - ~/scripts/nexus-notes-browse.sh — browse wrapper - ~/scripts/nexus-notes-new.sh — new note wrapper
- ~/scripts/nexus-notes-quick.sh — quick note wrapper - ~/.tmux/plugins/tmux-menus/items/nexus_notes.sh — menu definition - ~/.tmux/plugins/tmux-menus/items/main.sh — added NeXuS Notes entry

Backup: ~/backups/tmux-menus-backup-/

Usage: F12 | → NeXuS Notes → select action. Notes stored as dated .md files in ~/notes/nexus/


SESSION SUMMARY 2026-03-09/10 — Security stack audit + notes system (2026-03-10 00:03)

Session overview: Complete security stack audit. Diagnosed and fixed broken security tools (PSAD, fwsnort, fail2ban all non-functional despite appearing to run). Built CLI notes system in tmux popup.


DIAGNOSTIC FINDINGS

All three security tools were running but completely non-functional:

PSAD — not detecting anything

  • Root cause 1: klogd not running. Kernel iptables LOG entries go to /proc/kmsg (kernel ring buffer). Without klogd reading /proc/kmsg and forwarding to syslogd, entries never reach /var/log/messages. klogd binary present at /sbin/klogd but status=stopped, not in any runlevel.
  • Root cause 2: UFW before.rules had -A INPUT -j LOG and -A FORWARD -j LOG with NO --log-prefix. PSAD needs a prefix to identify firewall entries vs other kernel messages.
  • Root cause 3: psad.conf had SYSLOG_DAEMON=metalog but metalog is NOT the running syslog daemon. Busybox syslogd (/sbin/syslogd -t -n) is the actual daemon.
  • Root cause 4: metalog.conf had broken fail2ban section syntax (logdir = "/var/log/ missing closing quote and path) — not harmful since metalog not running but fixed for correctness.
  • Confirmed via: lsmod showing xt_LOG with 22 refs (rules active) but ip_tables with 0 refs; ps showing no klogd; /var/log/messages having zero kern.* entries; /var/log/ufw.log empty since Jan 2025.

fwsnort — rules never loaded

  • Root cause: fwsnort generates some rules with ! inside multiport port lists (e.g. --dports 25,!445,!1500). This is invalid syntax for iptables v1.8.11 (nf_tables backend). iptables-restore rejects the ENTIRE 29,672-rule ruleset at line 19885.
  • Scale: only 8 bad lines out of 29,672. All other rules valid.
  • Rules were last generated/attempted July 24 2025 — 7+ months stale.
  • Daily cron at /etc/periodic/daily/fwsnort exists but no root crontab entry for run-parts — daily updates never ran.
  • Confirmed via: grep 'dports.*,![0-9]' fwsnort_iptcmds.sh returning 8 hits.

fail2ban — watching empty file

  • Root cause: logpath in jail.d/alpine-ssh.conf pointed to /var/log/sshd_log (0 bytes, never written, created Jan 2025).
  • The correct path (/var/log/messages) was already commented out in the config file — someone knew the fix but left it inactive.
  • paths-common.conf defaults sshd_log to /var/log/auth.log which doesn't exist on Alpine with busybox syslogd.
  • auth.* facility routes to /var/log/messages on this system (confirmed with logger -p auth.info test).
  • fail2ban was running, jails started, pyinotify watching — just watching the wrong empty file.
  • Also confirmed: PermitRootLogin no already set in /etc/ssh/sshd_config.

FIXES APPLIED

Fix 1: UFW + klogd + PSAD logging chain

Script: ~/scripts/nexus-fix-psad-logging.sh (doas required) Changes: - /etc/ufw/before.rules: replaced '-A INPUT -j LOG' with '-A ufw-before-input -j LOG --log-prefix "[UFW BLOCK]" --log-level 4', same for FORWARD - /etc/psad/psad.conf: SYSLOG_DAEMON changed metalog → syslogd; IPT_PREFIX [UFW BLOCK] added after IPT_SYSLOG_FILE line - /etc/metalog.conf: fixed fail2ban section logdir missing closing quote (line 162) - /etc/conf.d/klogd: klogd added to boot runlevel via rc-update add klogd boot - Services restarted: klogd (started), ufw (reloaded), psad (restarted) Verified: scan from 192.168.1.127 immediately appeared in /var/log/messages with [UFW BLOCK] entries. PSAD created /var/log/psad/192.168.1.127/ directory.

Fix 2: fwsnort iptables-nft compatibility

Script: ~/scripts/nexus-fix-fwsnort-nftables.sh (doas required) Changes: - sed -i '/dports.,![0-9]/d; /sports.,![0-9]/d' /var/lib/fwsnort/fwsnort_iptcmds.sh - Removes 8 bad lines, applies remaining ~29,664 rules via IPTABLES=iptables sh fwsnort_iptcmds.sh - Signals PSAD with psad -H after load Note: Takes 5-10 minutes to apply (29,000+ individual iptables calls on this hardware).

Script: ~/scripts/nexus-update-fwsnort.sh — replacement for /usr/bin/update-fwsnort - Step 1: fwsnort --update-rules (fetch upstream ET rules) - Step 2: fwsnort (regenerate iptables commands) - Step 3: run nexus-fix-fwsnort-nftables.sh (strip 8 bad lines + apply) - Step 4: psad --sig-update && psad -H Install: doas cp ~/scripts/nexus-update-fwsnort.sh /usr/bin/update-fwsnort

Fix 3: fail2ban log path

Script: ~/scripts/nexus-fix-fail2ban.sh (doas required) Changes: - /etc/fail2ban/jail.d/alpine-ssh.conf: logpath changed from /var/log/sshd_log to /var/log/messages for both [sshd] and [sshd-ddos] jails; maxretry tightened from 10 to 5 - /etc/fail2ban/paths-overrides.local: created with sshd_log=/var/log/messages and syslog_authpriv=/var/log/messages to fix Alpine-wide default - fail2ban restarted Verified by user: fail2ban-client status working, jails active.


DOCUMENTATION CREATED

  • ~/scripts/docs/PSAD_MANUAL.md — complete PSAD manual: detection chain diagram, danger levels table, all daily commands, config reference, auto-block tuning, whitelist setup, troubleshooting, FAQ (10 questions), key files reference
  • ~/scripts/docs/FWSNORT_MANUAL.md — complete fwsnort manual: how fwsnort+PSAD work together, nft compat issue documented with exact error and fix, update workflow, all commands, signature categories, troubleshooting, FAQ (8 questions), key files reference

NOTES SYSTEM CREATED

See separate report entry for full detail. Summary: F12 | → NeXuS Notes → Browse/New/Quick. micro editor, glow preview, ~/notes/nexus/ storage.


BACKUPS CREATED THIS SESSION

  • ~/backups/psad-logging-fix-/ — before.rules, psad.conf, metalog.conf, klogd.conf
  • ~/backups/fwsnort-nft-fix-/ — fwsnort_iptcmds.sh, fwsnort.save
  • ~/backups/fail2ban-fix-/ — alpine-ssh.conf
  • ~/backups/tmux-menus-backup-/ — full tmux-menus plugin
  • ~/backups/fzf-speed-patch-/ — fzf-speed binary

STILL TODO (queued for next work)

  • AppArmor: add 'lsm=landlock,yama,apparmor' to /boot/extlinux.conf APPEND line; build profiles in complain mode for tor, privoxy, psad, nginx before enforcing
  • Lynis: fix broken install path, integrate into workflow, schedule regular audits
  • Port knocking: knockd setup for SSH
  • Security management TUI: unified interface for PSAD + fwsnort + fail2ban + AppArmor

Planned cage+foot nexus-terminal rebuild (2026-03-10 10:52)

What: Designed improved cage+foot CLI-first session with tmux escape hatch. Why: Previous nexus-terminal.desktop (cage -- foot) had no escape key — user got locked in. Also validated this is a real architecture not a throwaway: CLI-first system with on-demand GUI browser launch from within foot/cage. How: foot vs blackbox benchmark — foot wins (10-15MB vs 50-80MB, ~50ms vs ~300ms startup, Wayland-native C vs GTK4+libadwaita). Fix: run tmux inside foot so Ctrl+b d detaches and exit kills cage cleanly. Proposed change: nexus-terminal.desktop Exec= cage -- foot -e tmux Files: nexus-terminal.desktop — pending edit after labwc fix confirmed. Dependencies: cage, foot, tmux (all already installed)


NeXuS Time Stack — chrony NTS + Dead Man Switch (2026-03-18 02:14)

What: Created full NeXuS time management stack: chrony NTS config, interactive setup script, and dead man switch system.

Why: BusyBox ntpd has no NTS support — time sync was unauthenticated/unencrypted. DMS needed a paranoid privacy-respecting time stack with a configurable dead man switch for security use cases.

How: - chrony.conf: NTS over TLS to Cloudflare (time.cloudflare.com), Netnod (nts.netnod.se), NIST, PTB Germany. authselectmode require — refuses plain NTP. bindcmdaddress 127.0.0.1 for local-only command access. - nexus-time.sh: --sync, --status, --checkin, --dms-start , --dms-stop, --dms-status, --event, --events. DMS uses background watcher loop checking /tmp/nexus-dms.state every 60s. Fires configurable action script on deadline exceeded. - nexus-dms-fire.sh: Default DMS action — wall alert + log. User customises with wipe/notify/lockdown actions. - nexus-time-setup.sh: 17-option interactive menu. Sections: Time/Chrony (install, deploy, restart, test, sync, status), Startup/Services (view runlevels, add/remove from boot, stop), Dead Man Switch (arm, checkin, disarm, edit fire action). Live status indicators in menu header. Scriptable via args. - Fixed 'Cannot talk to daemon': original config had cmdport 0 with no bindcmdaddress — both command paths blocked. Fix: removed cmdport 0, added bindcmdaddress 127.0.0.1.

Files: - ~/scripts/chrony.conf — NTS config (deploy to /etc/chrony/chrony.conf) - ~/scripts/nexus-time.sh — time + DMS management script - ~/scripts/nexus-dms-fire.sh — DMS fire action (customise this) - ~/scripts/nexus-time-setup.sh — interactive setup/management menu

Dependencies: chrony (apk add chrony), at (apk add at for --event)


MEDIA window + Publishing Desk (2026-03-25 00:56)

What: Built the complete NeXuS MEDIA/SOCIAL tmux window stack and NeXuS Publishing Desk.

Why: User needed a dedicated MEDIA window with feed panes, crypto ticker, IRC, newsboat, and a publishing workflow for the NeXuS wiki/net.

How: - nexus-media.sh: tmux MEDIA window launcher — 4-pane layout: weechat (top-left), newsboat (bottom-left), nexus-media-feeds.sh (top-right), nexus-media-ticker.sh (bottom strip) - nexus-media-write.sh: NeXuS Publishing Desk — write markdown drafts, publish to local MkDocs wiki, GitHub Pages (mkdocs gh-deploy), or IPFS. Frontmatter auto-generated, draft:true removed on publish, IPFS CID log at ~/.nexus/ipfs_published.log - ~/.config/newsboat/urls: Configured with NeXuS GitHub, EFF, Tor Project, Schneier, HN Security, I2P News, LWN, Phoronix — all tagged for newsboat filtering - nexus-home-status.sh: Added TICKER section reading ~/.nexus/ticker.cache (written by nexus-media-ticker.sh); added [a] AI, [M] MEDIA key bindings - nexus-home-popup.sh: Added AI HUB, MEDIA, and PUBLISH entries to quick launch popup

Files: - ~/scripts/nexus-media.sh (NEW) - ~/scripts/nexus-media-write.sh (NEW) - ~/.config/newsboat/urls (NEW) - ~/scripts/nexus-home-status.sh (updated: ticker + key bindings) - ~/scripts/nexus-home-popup.sh (updated: AI/MEDIA/PUBLISH entries)


Darknet publish + Forge + RetroShare friend certs (2026-03-25 01:04)

What: Built nexus-darknet-publish.sh, nexus-forge.sh, nexus-retroshare.sh, and updated services.yaml with RetroShare replacing ZeroNet.

Why: User wants to publish content to Tor/I2P hidden services, sell digital goods via a darknet marketplace, and run RetroShare with a friend-cert bootstrap site so anyone can join the NeXuS mesh.

How: - nexus-darknet-publish.sh: Manages Tor hidden services + I2P eepsites. Appends HiddenServiceDir to torrc, adds i2pd tunnel config, spins python3 http.server on 127.0.0.1 per site. Sites DB at ~/.nexus/darknet-sites.cfg. Auto-generates starter index.html. [n] new site, [m] manage existing. - nexus-forge.sh: Digital goods marketplace. Listings stored as JSONL at ~/.nexus/forge/listings.jsonl. Products packaged to ~/.nexus/forge/products//. Generates HTML store pages at ~/.nexus/forge/store/. Categories: document/code/character/art/data/tool/audio. Price in XMR + Nexium. [n] new, [e] edit, [p] publish to store, [k] package+GPG encrypt. - nexus-retroshare.sh: RetroShare hub window with log pane. Manages retroshare-service/nogui daemon. [e] export your cert as NeXuS friend cert site (HTML at ~/.nexus/forge/store/nexus-friend-cert/index.html). [a] add friend cert. [d] open darknet publish to host the cert site. - nexus-retroshare-svc.sh: Shell contract for darknet TUI (start/stop/status/address). - services.yaml: Added retroshare service entry (depends on tor+i2p). - nexus-home-popup.sh: Added Forge, RetroShare, Darknet Pub, Publish entries.

Files: - ~/scripts/nexus-darknet-publish.sh (NEW) - ~/scripts/nexus-forge.sh (NEW) - ~/scripts/nexus-retroshare.sh (NEW) - ~/claude/nexus-darknet-go/scripts/nexus-retroshare-svc.sh (NEW) - ~/claude/nexus-darknet-go/services.yaml (updated: retroshare added) - ~/scripts/nexus-home-popup.sh (updated)


RetroShare full stack — GUI launcher + text companion (2026-03-25 02:09)

What: Full RetroShare window system — GUI launcher, management hub, and text chat/forum companion.

Why: RetroShare is Flatpak GUI. Needed: proper GUI launch on GUI sessions, text companion for contacts/chat/forums/channels in terminal, friend cert site builder.

How: - nexus-retroshare.sh: window launcher — detects GUI vs CLI session. GUI: 3-pane layout (hub + text chat companion + log strip). CLI: hub + log. Switches to existing window if open. - nexus-retroshare-hub.sh: management pane — launch Flatpak GUI, stop service, export cert (builds friend cert site), add friend cert, JSON API enable guide, darknet publish launcher. Shows profiles, stored certs, API status. - nexus-retroshare-chat.sh: text companion — connects to RetroShare JSON API (port 9090). Views: contacts (online/offline dots), direct chat (send/receive), forums (browse + posts), channels. Tab cycles views, fzf for peer/forum selection. Waits gracefully when API offline with enable instructions.

Files: - ~/scripts/nexus-retroshare.sh (rewritten: GUI-aware launcher) - ~/scripts/nexus-retroshare-hub.sh (NEW: management hub) - ~/scripts/nexus-retroshare-chat.sh (NEW: text chat/forum companion)

To activate text companion: RetroShare GUI → Plugins → Plugin Manager → JSON API → port 9090 → restart


WEB window + AV window (2026-03-25 03:09)

What: Two new tmux windows — WEB (text/GUI browser + Gemini + Gopher) and AV (audio/video).

Why: Dedicated windows for web browsing across protocols and media playback with download.

How: - nexus-web.sh: WEB window launcher — hub strip (top) + w3m pane (bottom-left) + amfora/Gemini (right-top) + sacc/Gopher (right-bottom) - nexus-web-hub.sh: hub — [/] search (DDG Lite, routes to any browser), [u] open URL, [k] clip URL to ~/.nexus/web-clips.log, [K] view clips, [b/B] bookmarks. GUI browser launchers: Mullvad, Tor Browser, Zen, Brave, Ungoogled, Falkon, Qutebrowser. Tor proxy auto-detected. - nexus-media-av.sh: AV window launcher — hub (left) + ncmpcpp/MPD (right-top) + mpv log (right-bottom) - nexus-av-hub.sh: [p] play file/URL via mpv (GUI=video window, CLI=audio only), [s] stream URL, [f] fzf browse media files, [Q] queue manager (m3u), [d] yt-dlp download (audio/video/playlist), [m] MPD start + quick controls, [a] alsamixer, [S] Strawberry GUI, [V] VLC. Tor proxy for yt-dlp. mpv IPC socket at /tmp/nexus-mpv-ipc.sock. - nexus-home-popup.sh: added [W] WEB, [A] AUDIO/VIDEO, [e] RETROSHARE

Files: ~/scripts/nexus-web.sh, nexus-web-hub.sh, nexus-media-av.sh, nexus-av-hub.sh (all NEW); nexus-home-popup.sh (updated)


nexus-hydra.sh — new hydra launcher with profiles (2026-04-02 08:41)

What: Global launcher for NeXuS Hydra new-hydra stack at ~/claude/demo-dark-stack/new-hydra/. Why: Old nexus-startup.sh in ~/git/nexus-hydra/ had no profile system — needed Ghost/Shadow/Recon/Stealth/Open network profiles added. How: Script auto-detects hardware tier (phantom/vanguard/hub/broadcast via RAM), maps NeXuS network profiles to compose tier args. Shadow=default daily driver, Ghost=all networks max Ghost Gate, Recon=Tor+I2P+Ygg+RetroShare, Stealth=phantom tier only, Open=phantom+stop Tor heads. Ghost Gate nft applied at start. Files: ~/scripts/nexus-hydra.sh. Dependencies: podman-compose, ~/claude/demo-dark-stack/new-hydra/


nexus-tmux-watch.sh — tmux intrusion monitor (2026-07-07 13:10)

Status: ✅ TESTED — running live

What: Background daemon watching the tmux socket for injection attacks and unknown connections.

Why: Node is under surveillance attention; needed active detection for tmux send-keys injection, rogue socket attachers, and permission tampering.

How: - Polls lsof on the tmux socket every 3s; baselines known PIDs on start - Alerts on any new PID touching the socket that wasn't in baseline - Watches ps for any tmux send-keys process (keystroke injection) - Monitors socket permission changes via stat - Parallel inotifywait on socket dir logs all access/open/write events - 10s alert cooldown prevents spam - Alerts via notify-send (desktop popup) + tmux display-message (status flash) + log

Files: - ~/scripts/nexus-tmux-watch.sh (new) - ~/.config/tmux/tmux.conf (autostart appended) - ~/logs/nexus-tmux-watch.log (runtime log) - ~/logs/nexus-inotify.log (raw socket access events)

Testing: Started live — PID 944 running, baseline captured (tmux server PID 6216), inotifywait active on socket dir.


nexus-lockdown.sh v2 + nexus-tmux-watch v2 — PWND response pipeline (2026-07-07 15:37)

Status: 🔵 DESIGNED — built and recovery tested, live attack test pending

What: Full incident response pipeline: detect → lock → snapshot → encrypt+sign → Ghost Gate permit → distribute to security stack → recover

Why: Live tmux send-keys injection test (by other Claude) proved session is vulnerable. Watcher v1 was blind. v2 catches injections via lsof PID monitoring. Lockdown issues GPG-signed Nostr kind 24000 permit to Ghost Gate.

How: - nexus-tmux-watch.sh v2: 1s lsof loop, inotifywait on socket, no hook (hook v1 locked everyone out) - nexus-lockdown.sh v2: lock → snapshot (ss/ps/lsof/last/dmesg) → SHA256 → GPG encrypt+sign → Ghost Gate permit (kind 24000 clearsigned JSON) → logger to PSAD/fail2ban/fwsnort/OpenSnitch → OSSEC stub → recovery mode - nexus-lockdown.sh --recover: issues all-clear permit, shows last report

Files: - ~/scripts/nexus-tmux-watch.sh (v2 rewrite) - ~/scripts/nexus-lockdown.sh (v2 — Ghost Gate + recovery) - ~/scripts/nexus-intrusion.filter.conf (fail2ban filter — needs doas cp to /etc/fail2ban/filter.d/) - ~/logs/ghost-gate/permits/ (signed permit queue) - ~/logs/intrusion/ (encrypted reports)

Pending: - Wire Nostr account into lockdown for real kind 24000 broadcast (Anon has account) - Install cs-firewall-bouncer + crowdsec-file-plugin + crowdsec-http-plugin (apk done) - Configure CrowdSec sovereign mode (share_custom/share_tainted → false) - watchbind TUI for intrusion console - doas cp nexus-intrusion.filter.conf → /etc/fail2ban/filter.d/


Created nexus-halt.sh — the stop code (2026-07-16 03:11)

Status: ✅ TESTED What: Emergency-stop command that halts NeXuS tmux frames/sessions (the 'stop code') — graceful by default, --hard/--panic on demand. Why: Before onboarding crew/frames that spawn tmux sessions, we needed a single kill switch. Fulfils the Emergency Stop Law. How: Whitelist-only reaper — acts on session names matching frame- or nexus via 'tmux ls'. Graceful path sends C-c to each pane then kill-session; --hard adds pkill -x with a core-process guard (never kills sh/fish/bash/login/tmux/init). Default spares the currently-attached session; --panic includes it. Previews + y/N confirm before killing in default mode. Files: ~/scripts/nexus-halt.sh, ~/scripts/nexus-halt.help.md Testing: Live-fire tested with throwaway sessions (frame-testcli, nexus-scratch, my-real-work). Verified: whitelist held (my-real-work survived --panic), short-name single halt works, --list is read-only, no-session paths are safe. sh -n clean. Dependencies: tmux. Integrates with nexus-frame.sh (frame- naming) and shows in the help pane via nexus-halt.help.md.


Built nexus-tv station — NeXuSistential terminal cinema (2026-07-16 08:18)

Status: 🔵 DESIGNED (builds + wires clean; real A/V playback untested — needs a live foot session) What: A transparent, keybound terminal-video cockpit. ncplayer (notcurses) draws the video, mpv carries the audio over an IPC socket, watchbind is the live control strip. Two players, each doing what it's best at. Why: notcurses has the best terminal-video blitters (pixel/sixel) but NO audio; mpv has audio + weaker sixel. Split the job across both = 'NeXuSistential'. User wanted it transparent, fluid, config-selectable, and re-syncable. How: nexus-tv.sh (engine) resolves YouTube via yt-dlp into codec-specific video + audio streams (presets: cinema/crisp/lofi/retro/audio; granular --vcodec/--acodec/-q/-b), runs ncplayer fg + mpv --no-video bg with --input-ipc-server. nexus-tv-station.sh builds a tmux frame (frame-tv): video pane + watchbind strip. nexus-tv-ctl.sh drives both players from watchbind keys (mpv via socat/IPC, ncplayer via tmux send-keys). SYNC: notcurses can't seek, so [ / ] NUDGE — briefly hold the player that's ahead so the other catches up. nexus-tv-status.sh paints title+progress+vol each -i 1 (fluid). Transparency inherited from foot alpha/blur. Files: ~/scripts/nexus-tv.sh, nexus-tv-station.sh, nexus-tv-ctl.sh, nexus-tv-status.sh Testing: sh -n clean on all 4; presets list OK; status strip degrades gracefully with no socket; TV_TEST frame build verified 2 panes (video engine + watchbind). NOT yet tested: real sixel playback, yt-dlp stream split, IPC pause/seek/vol/nudge against a live mpv — all need an interactive foot session with a wallpaper/display. Dependencies: ncplayer(notcurses+ffmpeg), mpv, yt-dlp, watchbind 0.2.1, socat, jq, tmux, foot. Integrates with nexus-halt.sh (frame-tv teardown).


Made TUI first-class — nexus-wb.sh (themed watchbind wrapper) (2026-07-16 08:30)

Status: 🔵 DESIGNED (assembly + wrapper logic verified; interactive launch needs a live tty) What: nexus-wb.sh turns ANY command into an interactive, keybound, dank-themed NeXuS TUI in one call — the first-class primitive for watchbind. Complements the existing wtfutil dashboard (nexus-dashboard.sh) as the two-primitive TUI layer. Why: 'make TUI first class.' watchbind proved itself in the TV cockpit but every use hand-rolled colors + keys. A NeXuS wrapper = consistent theme, standard keys, zero boilerplate. wtfutil half already exists (nexus-dashboard.sh) so NOT duplicated — avoided the ~/scripts/scripts triple-copy trap too. How: Wraps watchbind 0.2.1 with Catppuccin-Mocha named colors (header blue-bold, cursor black-on-blue, body white, selected magenta). Standard keys q/esc=quit, r=reload; user keys merged via --keys. --title prepends a styled header line using an argv-safe 'sh -c printf...; exec "$@"' wrapper (no eval, arg boundaries preserved). --print shows assembly without launching. Watched command after --. Files: ~/scripts/nexus-wb.sh, ~/scripts/nexus-wb.help.md Testing: sh -n clean; --print shows correct merged keybinds + header-lines; title-wrapper sh -c verified (prints header then execs command); no-command guard OK. NOT tested: live interactive render/colors (needs real foot tty). Dependencies: watchbind 0.2.1. Theme source: ~/.config/foot/foot.ini. Pairs with nexus-dashboard.sh (wtfutil).


Wired foot server mode into Wayland session + keybinds (2026-07-19 16:18)

Status: ✅ TESTED (static: bash -n + grep verify; not yet run in a live Wayland session)

What: Added foot --server to the Wayland session launcher and switched every terminal keybind across labwc/sway/wayfire from 'foot' to 'footclient', so all terminals share one server process (instant startup, one-foot RAM).

Why: On the E6520 (Sandy Bridge) spawning a fresh foot per window wastes RAM + startup time. foot-openrc revealed foot's server/daemon mode; footclient windows live inside a single foot --server.

How: - nexus-wayland-launcher.sh: new FOOT_SERVER toggle (line 34); start_foot_server() spawns 'foot --server' after the compositor socket is up, waits up to 5s for the server socket; called in main() before test_audio; cleanup() kills it on exit; show_info() advertises footclient + shows PID. Direct-spawn (not the etc/user/init.d/foot OpenRC user unit) because this launcher hand-manages its daemons with & and tears them down in cleanup. - labwc rc.xml: 8 commands foot->footclient (incl. grave/tdrop dropdown, audio C-A-s, cheatsheet W-slash). - sway config: two foot binds -> footclient AND set $term footclient (was alacritty). - wayfire.ini: command_terminal/audio/cheatsheet -> footclient.

Files: - ~/scripts/nexus-wayland-launcher.sh (backup .bak-20260719_160616) - ~/.config/labwc/rc.xml, ~/.config/sway/config, ~/.config/wayfire.ini (all backup .bak-20260719_161302)

Testing NOT done: live session run. Watch two things — the tdrop dropdown (grave key) under labwc (tdrop tracking a footclient window can be finicky), and confirm footclient connects (pgrep -a foot). Revert points: all .bak files above.

Dependencies: foot, footclient (installed), foot-openrc present but unused (we direct-spawn).


Fixed nexus-cheatsheet: pager scroll + accurate keybinds (2026-07-19 17:07)

Status: ✅ TESTED (runs clean, full box renders; verified on non-tty smoke test)

What: Reworked nexus-cheatsheet.py to page through less, and corrected the documented keybinds.

Why: Two bugs — (1) arrow keys/PgUp instantly closed the overlay because the raw single-byte reader closed on 0x1b (ESC) and every arrow/PgUp sequence starts with ESC; (2) the ~46-line box was taller than the screen (large font-size) with no scroll, so the top was cut off. Also the overlay mis-documented its own key (said CAT+Space opens the sheet; actually CAT+/ does, CAT+Space is a terminal).

How: - Replaced the os.system(clear)+lolcat+raw-tty key loop with: lolcat -f | less -R -F -X. less scrolls (arrows/PgUp/PgDn/g/G) and quits on q. Fallbacks: no lolcat -> plain text; no less -> plain dump. - Corrected NEXUS section: 'CAT + / This cheat sheet' + new 'CAT + Space Terminal (footclient)'; 'CAT + Return' now Terminal (footclient); added a FOOT SERVER note block (footclient / pgrep -a foot sanity). Footer now 'Scroll: up/down PgUp/PgDn g/G q to quit'.

Files: ~/scripts/nexus-cheatsheet.py (backups .bak-20260719_162309, _163541, _164725). Wrapper ~/scripts/nexus-cheatsheet.sh unchanged.

Testing: interactive less scroll confirmed by design; box alignment re-verified 54-wide (title/arrow rows are pre-existing wide-glyph, not mine).

Dependencies: less (702), lolcat (1.4), python3.


Created nexus-py.sh — natural/transparent Python envs (uv) (2026-07-19 17:07)

Status: ✅ TESTED (doctor/list/info/run all exercised against nexus-arsenal)

What: New wrapper that standardizes Python env management on uv, so every project behaves identically and no one ever runs 'source activate' (which differs in fish).

Why: Per-project venv+activate+pip ritual was repetitive and error-prone; venvs had drifted (project-local .venv plus centralized ~/.venv/{dank,caelestia,nexus-hydra}). uv was already installed (0.11.23) but unused as a standard.

How: subcommands run/env/add/info/shell/list/doctor. venv always at

/.venv; deps from requirements.txt (uv pip install) or pyproject.toml (uv sync); narrates every command (echoes the $ line before running). fish-aware shell subcommand. list maps every venv under $HOME.

Files: ~/scripts/nexus-py.sh, ~/scripts/nexus-py.help.md (new). Suggested fish abbr: abbr -a py 'sh ~/scripts/nexus-py.sh'.

Testing: full run path verified (env-ensure -> uv sync 222ms -> arg passthrough via --). Note: list flags ~/.venv container as '?' (cosmetic).

Dependencies: uv (engine; doas apk add uv), python3 3.14.5.


Curated nexus_netscanner_sink.pkgs (54 pkgs) for apk-sink (2026-07-19 17:07)

Status: 🔵 DESIGNED — manifest built + dry-run clean; live install pending

What: Self-identifying package manifest of network recon/monitor/mesh/capture tools for nexus-apk-sink.sh.

Why: User wanted to push a big 'netscanner kitchen sink' list through the conflict-aware installer.

How: Wrote ~/scripts/nexus_netscanner_sink.pkgs (54 pkgs, commented by category). Non-root dry run: 0 dropped (all resolve), 21 already installed, 33 would install, conflicts NOT pre-screened (needs root apk --simulate).

Files: ~/scripts/nexus_netscanner_sink.pkgs (new).

Testing/NEXT: run 'doas sh ~/scripts/nexus-apk-sink.sh -n -f ~/scripts/nexus_netscanner_sink.pkgs' (root dry run = real conflict pre-screen), then without -n to install. OPEN ISSUE: user reported live installs failing; root cause likely a broken apk world (every --simulate fails -> all bucketed conflict). Awaiting 'doas apk add --simulate netscanner' output to confirm.

Dependencies: nexus-apk-sink.sh, apk, root.


Hardened nexus-apk-sink — tolerate a dirty apk world (2026-07-20 04:38)

Status: ✅ TESTED (live run installed 33 netscanner pkgs: 0 conflict, 0 dropped)

What: Made the conflict-aware installer robust on machines that already have apk integrity errors. Why: With standing file-collision errors, apk exits non-zero on EVERY op; the sink read that as per-package conflict/failure → user saw 'all installs failing'. How: (1) baseline pre-existing error-lines via 'apk add --simulate busybox'; (2) flag a pkg as conflict only if it emits MORE error lines than baseline (not on raw exit code); (3) judge install success by 'apk info -e' STATE, not exit code (a dirty world makes apk lie). Files: ~/scripts/nexus-apk-sink.sh (backup .bak-20260719_183534). Testing: non-root dry run + live root run walked all 33; conflict/dropped both none. Dependencies: apk; root for --simulate.


apk world hygiene — removed apk-snap, fixed incus flavor collision (2026-07-20 04:38)

Status: ✅ TESTED (apk fix -s: 4 errors → 3 benign; btrfs spam gone)

What: Cleaned partial-upgrade + flavor drift with NO --force and NO destructive cascade. Why: 4 standing apk errors + btrfs snapshot-hook spam on every apk transaction. How: - Removed apk-snap (btrfs commit hook) — root is ext4-on-LVM so it failed every run; cascaded out snapper + btrfs-progs-libs (dead weight on ext4); btrfs-progs TOOLS kept. - incus: removed mismatched incus-feature-openrc (init for a feature daemon not installed); incus-openrc now owns /etc/init.d/incusd, matching the installed LTS incus daemon. - Left 3 benign file-collisions baselined by the hardened sink: 3proxy-doc/libproxy-doc, outils-doc/uutils-coreutils-doc, and freeradius-client/ppp-radius (removal cascades to 58 nagios pkgs — deliberately NOT done). - Method throughout: simulate-before-delete ('apk del -s'), never --force. The 58-pkg simulate is why. Files: system apk db only. Testing: apk fix -s ends at 3 benign errors; no btrfs hook output. Dependencies: apk; root.


Gen6 (Sandy Bridge / HD 3000) graphics tuning (2026-07-20 04:38)

Status: ✅ TESTED (configs applied+verified; VA-API driver installed; RAM read)

What: Enabled hardware video decode + GL threading + hardware cursors on the HD 3000. Why: video was CPU-decoded (mpv hwdec=no → garbled/choppy); launcher forced software cursors; no VA-API driver installed. How: - mpv.conf: hwdec=no → hwdec=vaapi (backup .bak-20260720_031532). - conf.d/nexus-graphics.fish (NEW): LIBVA_DRIVER_NAME=i965 + MESA_GLTHREAD=true. - nexus-wayland-launcher.sh: WLR_NO_HARDWARE_CURSORS now NVIDIA-only → Intel gets HW cursors (backup .bak-20260720_031532). - User installed libva-intel-driver + libva-utils (Gen6 needs legacy i965, NOT intel-media-driver / Gen8+). - Confirmed: Gen6 has NO Vulkan (ANV needs Gen7+); OpenGL 3.3 via crocus, Mesa 26.1.1. - RAM: 4GB ChannelA + 8GB ChannelB @1333 MT/s = dual-channel FLEX (8GB interleaved + 4GB single); 1333 is the SNB max. Files: ~/.config/mpv/mpv.conf, ~/.config/fish/conf.d/nexus-graphics.fish, ~/scripts/nexus-wayland-launcher.sh. Testing: configs load/verify; live playback gain pending a Wayland session. Optional kernel flags (i915.enable_fbc=1 fastboot=1) NOT applied (needs /boot edit + reboot). Dependencies: libva-intel-driver, libva-utils, mesa/crocus.


Created nexus-node-guards.sh + nexus-dmi-mem.py (universal node tools) (2026-07-20 04:38)

Status: ✅ TESTED (guards report matches real state; dmi parser output correct)

What: Two universal NeXuS-node tools distilling this session's install invariants. Why: keep NeXuS installs universal — probe hardware/state, never assume; and replace a tool that hangs the box. How: - nexus-node-guards.sh (+.help.md): guards = snapshots (apk-snap only on btrfs), gpu (install only the mesa-vulkan/VA-API driver the GPU can use; Gen6 = no Vulkan), flavors (warn on two-impls-per-slot). Modes report/apply; encodes 6 invariants (probe-dont-assume, tolerate dirty world, never --force, simulate-before-delete, one-flavor-per-slot, usable-HW-only). Fixed a pipe-subshell scoping bug in the flavors guard. - nexus-dmi-mem.py: reads SMBIOS Type-17 from /sys/firmware/dmi/tables/DMI ONLY — safe replacement for 'dmidecode -t 17', which hangs the E6520 in uninterruptible D-state via /dev/mem (timeout can't kill it). Reports per-slot Locator/Bank/Size/Speed + symmetric/flex/single channel verdict. Files: ~/scripts/nexus-node-guards.sh (+.help.md), ~/scripts/nexus-dmi-mem.py (NEW). Testing: guards report matched real box (ext4/no-apk-snap, Gen6/no-Vulkan, 3 flavor collisions, incus clean); dmi parser produced correct 4+8GB flex report under doas. Dependencies: apk, lspci, findmnt (guards); python3 + root (dmi reader).


Gen6 video — VERIFIED end-to-end (post-reboot live test) (2026-07-20 05:14)

Status: ✅ TESTED (live playback confirmed on first reboot after the changes)

What: Confirmed the Gen6 video stack works in a real Wayland session — closes the 'pending playback' note on the earlier gen6-graphics entry.

Verified: - vainfo: i965 driver 2.4.1 loaded; H.264 (baseline/main/high) + MPEG-2 hardware decode profiles present (H.264 encode too). - fish env survived reboot: LIBVA_DRIVER_NAME=i965, MESA_GLTHREAD=true active. - mpv .mp4 with hwdec=vaapi + vo=gpu: played CLEAN, no garbage, LOW CPU (= VAAPI offload real). - The magenta terminal corruption in ~/screenshots/20260720_003652.png was PRE-FIX (00:36, before 03:15 changes) → resolved.

Notes: - mpv build has NO dmabuf-wl (runtime 'not found'); correct outputs are gpu / gpu-next / drm(TTY). mpv.conf comment fixed accordingly. - vainfo prints a benign 'wl_drm_interface Symbol not found' (Wayland probe falls back to DRM) — does not affect mpv. - Optional/unapplied: i915.enable_fbc=1 fastboot=1 (needs /boot edit + reboot). RAM needs nothing (dual-channel flex @1333 = SNB max).

Files: ~/.config/mpv/mpv.conf (comment fix).


Fixed Chromium garbage on Gen6 (disable GPU rasterization) (2026-07-20 07:47)

Status: ✅ TESTED (user confirmed: clean, no more garbage)

What: Chromium rendered corrupted/garbage on the HD 3000 while Firefox was fine. Why: chrome://gpu showed Chromium using ANGLE→OpenGL ES 3.0 on crocus with 'Rasterization: Hardware accelerated' — HW raster through ANGLE/GLES on Sandy Bridge paints garbage. Firefox uses a different (WebRender/software) path. How: Set CHROMIUM_USER_FLAGS='--disable-gpu-rasterization' in ~/.config/fish/conf.d/nexus-graphics.fish (the Alpine chromium wrapper appends CHROMIUM_USER_FLAGS — no root). Moves rasterization to CPU while KEEPING hardware compositing + hardware video decode (VAAPI). Least-aggressive fix (not --disable-gpu). Files: ~/.config/fish/conf.d/nexus-graphics.fish. Testing: user confirmed clean render after relaunch. Note: launcher(fuzzel)-spawned chromium needs next Wayland session to inherit the env; terminal-launched picks it up immediately. Dependencies: chromium (Alpine wrapper reads /etc/chromium/*.conf + CHROMIUM_USER_FLAGS).


Created nexus-quickshell.sh + tmux-menus DankShell entry (prefix-) (2026-07-28 13:54)

Status: ✅ TESTED (syntax/wiring) · 🔵 runtime start not yet exercised (Dank already running bare)

What: Manage DankShell (quickshell via dms run) inside a persistent tmux session 'dank', with a prefix-\ menu entry + labwc autostart hook. One wrapper = single source of truth.

Why: Anon wanted quickshell/Dank run under tmux for attachable logs + clean lifecycle on a systemd-less Alpine box; and a prefix-\ tmux-menus entry to drive it.

How: - ~/scripts/nexus-quickshell.sh {start|stop|restart|logs|status}. start: tmux new-session -d -s dank 'exec dms run' (env-guarded on WAYLAND_DISPLAY; exec => clean signals; stderr in scrollback = live log). stop: dms kill + kill session. logs: switch-client -t dank (in tmux) else attach. status: popup (in tmux) showing session/process/WAYLAND state. - tmux-menus (LIVE copy = ~/.tmux/plugins/tmux-menus, loaded by ~/.tmux/plugins/tpm per ~/.config/tmux/tmux.conf): new items/nexus_quickshell.sh submenu mirroring nexus_notes.sh; registered in items/main.sh as 0.0 M Q "DankShell (dms) ..." nexus_quickshell.sh. - labwc autostart: swapped the nexus-desktop case from quickshell -p /usr/local/share/quickshell/dms & to "$HOME/scripts/nexus-quickshell.sh" start &.

Files: ~/scripts/nexus-quickshell.sh (NEW); ~/.tmux/plugins/tmux-menus/items/nexus_quickshell.sh (NEW); ~/.tmux/plugins/tmux-menus/items/main.sh (EDIT, bak-quickshell-); ~/.config/labwc/autostart (EDIT, bak-quickshell-).

Caveats/next: Current desktop reports XDG_CURRENT_DESKTOP=labwc:wlroots (NOT nexus-desktop), and Dank is already running as bare qs -p ... (PID observed) outside tmux — so the edited nexus-desktop autostart case may not be Anon's actual launch path. Duplication trap: 3 tmux-menus copies exist; edited only the LIVE ~/.tmux/plugins one. To migrate the running instance under tmux now: nexus-quickshell.sh stop then start. TPM update (prefix+U) could overwrite the custom menu items (same risk as existing nexus_notes.sh).


Wired latest canon into TUI desktop hubs (2026-07-30 19:45)

Status: ✅ TESTED (syntax-validated, fossil committed)

What: Updated three core TUI desktop hub scripts to include all recent NeXuS canonical components.

Why: The popup, web-hub, and home-status were referencing old/missing paths and were missing the entire AI proxy stack, new darknet scripts, and recently-built apps.

How: - nexus-home-popup.sh: Added 8 new LINKS entries (AI HOME, PROXY, DASHBOARD, CHAR CARD, OPEN CHARS, AI PARTY, VM FORGE, NXS SEARCH); added DARKNET PANEL and NET DOCTOR; updated DARKNET path from ~/claude/nexus-darknet-go to ~/Projects/nexus-network-stack/network/configs/darknet-stack; fixed case-insensitive key matching bug (tolower→exact ==k) that caused uppercase keys to always fallthrough to lowercase match - nexus-web-hub.sh: Added _proxy_dot() + _open_proxy() helpers; added NEXUS PROXY section to draw (H/P/O/C/S keys); fixed [H] from old nexus-serve.sh binary to open https://localhost:8443/; added P=manager, O=OpenCharacters, C=charcard, S=NXS-search - nexus-home-status.sh: Added 3 inline service checks at top of SERVICES loop: NeXuS Proxy (:8443), NXS Search (:5000), Darknet Panel (:8878)

Files: ~/scripts/nexus-home-popup.sh, ~/scripts/nexus-web-hub.sh, ~/scripts/nexus-home-status.sh (all backed up as .bak-20260730)

Fossil: d9a6f106 in nexus-scripts.fossil

Key canonical paths now wired: - Proxy: ~/scripts/nexus-api-proxy.sh - Party: ~/claude/nexus-party/nexus-party.sh - VM Forge: ~/git/nexus-vm-forge/nexus-vm-forge.sh - Darknet: ~/Projects/nexus-network-stack/network/configs/darknet-stack/nexus-darknet - Search: http://localhost:5000 (~/NeXuS/nxs-search)


TUI desktop + NXS Search + tmux prefix fixes (2026-08-02 19:54)

Status: ✅ TESTED

What: Multiple desktop and infrastructure fixes across this session.

NXS Search fix: - Filtered .cache/.npm/.cargo/node_modules/.git paths from filename search results - Was: 100 results all from ~/.cache/damin — now: clean real paths - Created Fossil: ~/museum/nexus-nxs-search.fossil - Existing index (529K files) reused — no re-scan needed

tmux prefix change: - C-z → C-a (frees Ctrl-Z for Claude Code suspend and Unix SIGTSTP) - Old C-a (launch_app.sh) moved to C-M-l (Ctrl+Alt+L) - Updated cheatsheet + popup page 3 to show new prefix

TUI desktop updates (nexus-apps-hub.sh): - New APPS window hub with all web frontends + live status dots - Wired: Command Center :8800, Darknet Panel :8878, App Arsenal :8080 - Fixed nexus-web-hub.sh darknet_dash: was trying to build a Go binary → now starts FastAPI Command Center - Popup page 1: added h|APPS HUB, Y|AI FOUNDRY; page 2: L|APP ARSENAL - All changes committed to nexus-scripts.fossil

Files: ~/.config/tmux/tmux.conf, ~/scripts/nexus-apps-hub.sh (new), ~/scripts/nexus-apps.sh (new), ~/scripts/nexus-home-popup.sh, ~/scripts/nexus-ai-hub.sh, ~/scripts/nexus-web-hub.sh, ~/scripts/tmux-cheatsheet.sh, ~/NeXuS/nxs-search/backend/app.py, ~/NeXuS/nxs-search/nexus-search-reindex.sh


nexus-stack-start.sh + aliases + nexus-api-proxy cert update (2026-08-17 16:28)

Status: ✅ TESTED. What: (1) nexus-stack-start.sh — full NeXuS web stack manager with start/stop/status/restart and --full flag for DivaChain. (2) nexus-api-proxy.sh updated to use NeXuS CA cert + env var paths + certigo cert verification on start. (3) Fish aliases added: api-proxy (existing), nncc, diva, nexus-stack. Why: needed a single command to bring up the full NeXuS stack in correct order. How: nexus-stack-start.sh starts in order: step-ca → web-server → nncc → wiki → (diva with --full). Idempotent (checks if already running). Status shows all 7 services with live/stopped and cert info via certigo. Cyberpunk-themed ANSI output (cyan/magenta/orange, no yellow). Files: ~/scripts/nexus-stack-start.sh (NEW), ~/scripts/nexus-api-proxy.sh (updated), ~/.config/fish/config.fish (4 aliases).