feat: rootless podman, session hardening, boot stability, sidebar fix

Rootless podman migration (TASK-11):
- Remove sudo from all podman calls in PodmanClient + 8 backend files
- Remove sudo from all podman/docker calls in deploy script
- Restore full systemd security hardening: NoNewPrivileges,
  RestrictAddressFamilies, MemoryDenyWriteExecute, RestrictRealtime,
  RestrictNamespaces, RestrictSUIDSGID, SystemCallFilter, ProtectSystem=strict
- Enable loginctl linger for rootless container persistence
- Remove Ollama from auto-deploy (marketplace-only)

Session & auth hardening:
- Increase MAX_CONCURRENT_SESSIONS 20→50 (prevents eviction storms)
- Debounced 401 redirect in rpc-client.ts (prevents redirect storms)

Boot stability:
- optimize-debian.sh: adds chrony, swap, removes policy-rc.d
- deploy script: pre-restart chrony + swap setup
- ISO build: chrony package, swap file creation
- BootScreen: no longer clears localStorage (prevents splash replay)
- RootRedirect: sole owner of localStorage clearing on server ready

UI fixes:
- Sidebar opacity default changed from 0→visible (fixes missing sidebar
  after page-persistence login without entrance animation)
- Console.log/error wrapped in import.meta.env.DEV guards
- Remove unused route import from RootRedirect

Beta tracking:
- CLAUDE.md: beta freeze protocol added
- MASTER_PLAN.md: TASK-11, TASK-17, phase structure
- BETA-PROGRESS.md: initial tracking doc
- Tagged v1.2.0-alpha.1 as pre-rootless baseline

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-03-18 13:53:27 +00:00
co-authored by Claude Opus 4.6
parent 934d120243
commit 870ff095d8
48 changed files with 2979 additions and 2196 deletions
+4 -3
View File
@@ -176,12 +176,13 @@ onMounted(async () => {
window.addEventListener('touchstart', onUserActivity)
const seenIntro = localStorage.getItem('neode_intro_seen') === '1'
const isDirectRoute = route.path !== '/'
const fromBoot = route.query.intro === '1'
const fromBoot = sessionStorage.getItem('archipelago_from_boot') === '1'
if (fromBoot) sessionStorage.removeItem('archipelago_from_boot')
if (import.meta.env.DEV) console.log('[App] onMounted — seenIntro:', seenIntro, 'fromBoot:', fromBoot)
if (fromBoot && !seenIntro) {
// Coming from boot screen — show the full splash intro
// Coming from boot screen — show the full splash intro (Enter to Exit → typing → logo)
showSplash.value = true
// SplashScreen will emit 'complete' → handleSplashComplete
} else if (!seenIntro && !isDirectRoute && import.meta.env.VITE_DEV_MODE !== 'boot') {
// Normal first visit (not boot mode) — show splash intro
showSplash.value = true