Files
docs/RESUME/index.html
T

2651 lines
64 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="description" content="Single source of truth for the homelab">
<link rel="canonical" href="http://192.168.1.8:13080/RESUME/">
<link rel="prev" href="../CHANGELOG/">
<link rel="next" href="../ct-inventory/">
<link rel="icon" href="../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.6">
<title>Resume - nuclide.systems docs</title>
<link rel="stylesheet" href="../assets/stylesheets/main.484c7ddc.min.css">
<link rel="stylesheet" href="../assets/stylesheets/palette.ab4e12ef.min.css">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback">
<style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style>
<script>__md_scope=new URL("..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
</head>
<body dir="ltr" data-md-color-scheme="slate" data-md-color-primary="black" data-md-color-accent="blue">
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" for="__drawer"></label>
<div data-md-component="skip">
<a href="#session-resume" class="md-skip">
Skip to content
</a>
</div>
<div data-md-component="announce">
</div>
<header class="md-header" data-md-component="header">
<nav class="md-header__inner md-grid" aria-label="Header">
<a href=".." title="nuclide.systems docs" class="md-header__button md-logo" aria-label="nuclide.systems docs" data-md-component="logo">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"/></svg>
</a>
<label class="md-header__button md-icon" for="__drawer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg>
</label>
<div class="md-header__title" data-md-component="header-title">
<div class="md-header__ellipsis">
<div class="md-header__topic">
<span class="md-ellipsis">
nuclide.systems docs
</span>
</div>
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
Resume
</span>
</div>
</div>
</div>
<form class="md-header__option" data-md-component="palette">
<input class="md-option" data-md-color-media="(prefers-color-scheme: dark)" data-md-color-scheme="slate" data-md-color-primary="black" data-md-color-accent="blue" aria-hidden="true" type="radio" name="__palette" id="__palette_0">
<input class="md-option" data-md-color-media="(prefers-color-scheme: light)" data-md-color-scheme="default" data-md-color-primary="black" data-md-color-accent="blue" aria-hidden="true" type="radio" name="__palette" id="__palette_1">
</form>
<script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
<label class="md-header__button md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
</label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
<label class="md-search__icon md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
</label>
<nav class="md-search__options" aria-label="Search">
<button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
</button>
</nav>
<div class="md-search__suggest" data-md-component="search-suggest"></div>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix>
<div class="md-search-result" data-md-component="search-result">
<div class="md-search-result__meta">
Initializing search
</div>
<ol class="md-search-result__list" role="presentation"></ol>
</div>
</div>
</div>
</div>
</div>
</nav>
</header>
<div class="md-container" data-md-component="container">
<nav class="md-tabs" aria-label="Tabs" data-md-component="tabs">
<div class="md-grid">
<ul class="md-tabs__list">
<li class="md-tabs__item">
<a href=".." class="md-tabs__link">
Home
</a>
</li>
<li class="md-tabs__item">
<a href="../CHANGELOG/" class="md-tabs__link">
Changelog
</a>
</li>
<li class="md-tabs__item md-tabs__item--active">
<a href="./" class="md-tabs__link">
Resume
</a>
</li>
<li class="md-tabs__item">
<a href="../ct-inventory/" class="md-tabs__link">
CT inventory
</a>
</li>
<li class="md-tabs__item">
<a href="../infra/proxmox-state/" class="md-tabs__link">
Infra
</a>
</li>
<li class="md-tabs__item">
<a href="../services/homelab-architecture/" class="md-tabs__link">
Services
</a>
</li>
<li class="md-tabs__item">
<a href="../security/data-leak-audit-comparison/" class="md-tabs__link">
Security & audits
</a>
</li>
<li class="md-tabs__item">
<a href="../ideas/stack-ideas/" class="md-tabs__link">
Ideas
</a>
</li>
<li class="md-tabs__item">
<a href="../history/traefik-migration/" class="md-tabs__link">
History
</a>
</li>
</ul>
</div>
</nav>
<main class="md-main" data-md-component="main">
<div class="md-main__inner md-grid">
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary md-nav--lifted" aria-label="Navigation" data-md-level="0">
<label class="md-nav__title" for="__drawer">
<a href=".." title="nuclide.systems docs" class="md-nav__button md-logo" aria-label="nuclide.systems docs" data-md-component="logo">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"/></svg>
</a>
nuclide.systems docs
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href=".." class="md-nav__link">
<span class="md-ellipsis">
Home
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../CHANGELOG/" class="md-nav__link">
<span class="md-ellipsis">
Changelog
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
<span class="md-ellipsis">
Resume
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<a href="./" class="md-nav__link md-nav__link--active">
<span class="md-ellipsis">
Resume
</span>
</a>
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#open-items-urgency-order" class="md-nav__link">
<span class="md-ellipsis">
Open items (urgency order)
</span>
</a>
<nav class="md-nav" aria-label="Open items (urgency order)">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#critical-security-risk-or-unrecoverable-data-loss" class="md-nav__link">
<span class="md-ellipsis">
🔴 Critical — security risk or unrecoverable data loss
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#high-known-broken-verification-needed" class="md-nav__link">
<span class="md-ellipsis">
🟠 High — known broken / verification needed
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#medium-incomplete-migrations-cleanup-debt" class="md-nav__link">
<span class="md-ellipsis">
🟡 Medium — incomplete migrations / cleanup debt
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#planned-requires-infrastructure-or-significant-effort" class="md-nav__link">
<span class="md-ellipsis">
🔵 Planned — requires infrastructure or significant effort
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#recently-completed-2026-05-26" class="md-nav__link">
<span class="md-ellipsis">
Recently completed (2026-05-26)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#recently-completed-2026-05-24" class="md-nav__link">
<span class="md-ellipsis">
Recently completed (2026-05-24)
</span>
</a>
<nav class="md-nav" aria-label="Recently completed (2026-05-24)">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#vault-obsidian" class="md-nav__link">
<span class="md-ellipsis">
Vault + Obsidian
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#config-to-git-fleet-expanded-to-8-repos" class="md-nav__link">
<span class="md-ellipsis">
Config-to-git fleet expanded to 8 repos
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#networking-nuclidelan-zone" class="md-nav__link">
<span class="md-ellipsis">
Networking — *.nuclide.lan zone
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#homarr" class="md-nav__link">
<span class="md-ellipsis">
Homarr
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#pocket-id" class="md-nav__link">
<span class="md-ellipsis">
Pocket-ID
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#other" class="md-nav__link">
<span class="md-ellipsis">
Other
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#recently-completed-2026-05-23-session-continued-4" class="md-nav__link">
<span class="md-ellipsis">
Recently completed (2026-05-23, session continued ×4)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#recently-completed-2026-05-23-session-continued-3" class="md-nav__link">
<span class="md-ellipsis">
Recently completed (2026-05-23, session continued ×3)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#recently-completed-2026-05-23-session-continued-2" class="md-nav__link">
<span class="md-ellipsis">
Recently completed (2026-05-23, session continued ×2)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#recently-completed-2026-05-23-session-continued" class="md-nav__link">
<span class="md-ellipsis">
Recently completed (2026-05-23, session continued)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#recently-completed-2026-05-23" class="md-nav__link">
<span class="md-ellipsis">
Recently completed (2026-05-23)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#recently-completed-session-continued-2-2026-05-22" class="md-nav__link">
<span class="md-ellipsis">
Recently completed (session continued ×2, 2026-05-22)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#recently-completed-session-continued-2026-05-22" class="md-nav__link">
<span class="md-ellipsis">
Recently completed (session continued, 2026-05-22)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#recently-completed-this-session-2026-05-22" class="md-nav__link">
<span class="md-ellipsis">
Recently completed (this session, 2026-05-22)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#key-system-state" class="md-nav__link">
<span class="md-ellipsis">
Key system state
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#constraints-to-remember" class="md-nav__link">
<span class="md-ellipsis">
Constraints to remember
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../ct-inventory/" class="md-nav__link">
<span class="md-ellipsis">
CT inventory
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_5" >
<label class="md-nav__link" for="__nav_5" id="__nav_5_label" tabindex="0">
<span class="md-ellipsis">
Infra
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_5_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_5">
<span class="md-nav__icon md-icon"></span>
Infra
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../infra/proxmox-state/" class="md-nav__link">
<span class="md-ellipsis">
Proxmox state
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../infra/portmap/" class="md-nav__link">
<span class="md-ellipsis">
Port map
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../infra/storage/" class="md-nav__link">
<span class="md-ellipsis">
Storage
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../infra/volumes/" class="md-nav__link">
<span class="md-ellipsis">
Volumes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../infra/docker-networks/" class="md-nav__link">
<span class="md-ellipsis">
Docker networks
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../infra/connection-hosts/" class="md-nav__link">
<span class="md-ellipsis">
Connection hosts
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../infra/proxmox-memory-audit/" class="md-nav__link">
<span class="md-ellipsis">
Memory audit
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_6" >
<label class="md-nav__link" for="__nav_6" id="__nav_6_label" tabindex="0">
<span class="md-ellipsis">
Services
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_6_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_6">
<span class="md-nav__icon md-icon"></span>
Services
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../services/homelab-architecture/" class="md-nav__link">
<span class="md-ellipsis">
Homelab architecture
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../services/dev-environment/" class="md-nav__link">
<span class="md-ellipsis">
Dev environment (Coder + Gitea)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../services/mcp-gateway/" class="md-nav__link">
<span class="md-ellipsis">
MCP gateway
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../services/mcp-servers/" class="md-nav__link">
<span class="md-ellipsis">
MCP servers
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../services/pocket-id/" class="md-nav__link">
<span class="md-ellipsis">
Pocket-ID (OIDC)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../services/backrest/" class="md-nav__link">
<span class="md-ellipsis">
Backrest (backups)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../services/databases/" class="md-nav__link">
<span class="md-ellipsis">
Databases
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../services/secrets-manager/" class="md-nav__link">
<span class="md-ellipsis">
Secrets manager
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../services/comfyui/" class="md-nav__link">
<span class="md-ellipsis">
ComfyUI
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../services/zoraxy/" class="md-nav__link">
<span class="md-ellipsis">
Zoraxy
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../services/adguard-dns/" class="md-nav__link">
<span class="md-ellipsis">
AdGuard DNS
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../services/cloud-gpu/" class="md-nav__link">
<span class="md-ellipsis">
Cloud GPU
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../services/arcane/" class="md-nav__link">
<span class="md-ellipsis">
Arcane
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../services/doc-ingestion/" class="md-nav__link">
<span class="md-ellipsis">
Doc ingestion pipeline
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../services/llm-benchmark/" class="md-nav__link">
<span class="md-ellipsis">
LLM benchmark
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_7" >
<label class="md-nav__link" for="__nav_7" id="__nav_7_label" tabindex="0">
<span class="md-ellipsis">
Security & audits
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_7_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_7">
<span class="md-nav__icon md-icon"></span>
Security & audits
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../security/data-leak-audit-comparison/" class="md-nav__link">
<span class="md-ellipsis">
Comparison
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../security/data-leak-audit-2026-05-20-tr004-cloud-sandbox/" class="md-nav__link">
<span class="md-ellipsis">
2026-05-20 · cloud-sandbox breach
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../security/data-leak-audit-2026-05-21-tr004-artifacts/" class="md-nav__link">
<span class="md-ellipsis">
2026-05-21 · artifacts (clean)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../security/audit-claude-code-meta/" class="md-nav__link">
<span class="md-ellipsis">
Self-audit (Claude Code)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../security/transcripts/audit-chat-2026-05-21/" class="md-nav__link">
<span class="md-ellipsis">
Transcript (audit session)
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_8" >
<label class="md-nav__link" for="__nav_8" id="__nav_8_label" tabindex="0">
<span class="md-ellipsis">
Ideas
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_8_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_8">
<span class="md-nav__icon md-icon"></span>
Ideas
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../ideas/stack-ideas/" class="md-nav__link">
<span class="md-ellipsis">
Stack ideas
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_9" >
<label class="md-nav__link" for="__nav_9" id="__nav_9_label" tabindex="0">
<span class="md-ellipsis">
History
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_9_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_9">
<span class="md-nav__icon md-icon"></span>
History
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../history/traefik-migration/" class="md-nav__link">
<span class="md-ellipsis">
Traefik (abandoned 2026-05-16)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../history/traefik-migration-docker-labels/" class="md-nav__link">
<span class="md-ellipsis">
Traefik labels (abandoned)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../history/mcp-gateway-requirements/" class="md-nav__link">
<span class="md-ellipsis">
MCP gateway requirements (superseded)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../history/scrubbing-list-2026-05-17/" class="md-nav__link">
<span class="md-ellipsis">
Scrubbing list (2026-05-17)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../history/case-study/" class="md-nav__link">
<span class="md-ellipsis">
Case study
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#open-items-urgency-order" class="md-nav__link">
<span class="md-ellipsis">
Open items (urgency order)
</span>
</a>
<nav class="md-nav" aria-label="Open items (urgency order)">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#critical-security-risk-or-unrecoverable-data-loss" class="md-nav__link">
<span class="md-ellipsis">
🔴 Critical — security risk or unrecoverable data loss
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#high-known-broken-verification-needed" class="md-nav__link">
<span class="md-ellipsis">
🟠 High — known broken / verification needed
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#medium-incomplete-migrations-cleanup-debt" class="md-nav__link">
<span class="md-ellipsis">
🟡 Medium — incomplete migrations / cleanup debt
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#planned-requires-infrastructure-or-significant-effort" class="md-nav__link">
<span class="md-ellipsis">
🔵 Planned — requires infrastructure or significant effort
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#recently-completed-2026-05-26" class="md-nav__link">
<span class="md-ellipsis">
Recently completed (2026-05-26)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#recently-completed-2026-05-24" class="md-nav__link">
<span class="md-ellipsis">
Recently completed (2026-05-24)
</span>
</a>
<nav class="md-nav" aria-label="Recently completed (2026-05-24)">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#vault-obsidian" class="md-nav__link">
<span class="md-ellipsis">
Vault + Obsidian
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#config-to-git-fleet-expanded-to-8-repos" class="md-nav__link">
<span class="md-ellipsis">
Config-to-git fleet expanded to 8 repos
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#networking-nuclidelan-zone" class="md-nav__link">
<span class="md-ellipsis">
Networking — *.nuclide.lan zone
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#homarr" class="md-nav__link">
<span class="md-ellipsis">
Homarr
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#pocket-id" class="md-nav__link">
<span class="md-ellipsis">
Pocket-ID
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#other" class="md-nav__link">
<span class="md-ellipsis">
Other
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#recently-completed-2026-05-23-session-continued-4" class="md-nav__link">
<span class="md-ellipsis">
Recently completed (2026-05-23, session continued ×4)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#recently-completed-2026-05-23-session-continued-3" class="md-nav__link">
<span class="md-ellipsis">
Recently completed (2026-05-23, session continued ×3)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#recently-completed-2026-05-23-session-continued-2" class="md-nav__link">
<span class="md-ellipsis">
Recently completed (2026-05-23, session continued ×2)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#recently-completed-2026-05-23-session-continued" class="md-nav__link">
<span class="md-ellipsis">
Recently completed (2026-05-23, session continued)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#recently-completed-2026-05-23" class="md-nav__link">
<span class="md-ellipsis">
Recently completed (2026-05-23)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#recently-completed-session-continued-2-2026-05-22" class="md-nav__link">
<span class="md-ellipsis">
Recently completed (session continued ×2, 2026-05-22)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#recently-completed-session-continued-2026-05-22" class="md-nav__link">
<span class="md-ellipsis">
Recently completed (session continued, 2026-05-22)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#recently-completed-this-session-2026-05-22" class="md-nav__link">
<span class="md-ellipsis">
Recently completed (this session, 2026-05-22)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#key-system-state" class="md-nav__link">
<span class="md-ellipsis">
Key system state
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#constraints-to-remember" class="md-nav__link">
<span class="md-ellipsis">
Constraints to remember
</span>
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<article class="md-content__inner md-typeset">
<h1 id="session-resume">Session Resume<a class="headerlink" href="#session-resume" title="Permanent link">&para;</a></h1>
<p>Last updated: 2026-05-26.</p>
<h2 id="open-items-urgency-order">Open items (urgency order)<a class="headerlink" href="#open-items-urgency-order" title="Permanent link">&para;</a></h2>
<h3 id="critical-security-risk-or-unrecoverable-data-loss">🔴 Critical — security risk or unrecoverable data loss<a class="headerlink" href="#critical-security-risk-or-unrecoverable-data-loss" title="Permanent link">&para;</a></h3>
<ul>
<li>[ ] <strong>Password rotation: <code>tapirnase</code></strong> — shared across WiFi PSK, LiteLLM root key (<code>sk-tapirnase</code>), D-Link admin, Backrest repo password, HAOS Terminal &amp; SSH addon password. Single sniff = broad blast radius. Rotate per-service. See <code>services/homelab-architecture.md</code> §operational rules.</li>
<li>[ ] <strong>Nextcloud Borg passphrase → Vaultwarden</strong> — passphrase only in container env; CT 105 loss = unrecoverable backup. Move to Vaultwarden. See <code>services/backrest.md</code> blind spot #4b.</li>
<li>[ ] <strong>Vault secrets sweep</strong> — 32 plaintext secrets in Obsidian vault notes (Anthropic key, Gemini, NC AIO passphrase, etc.). Tracker at <code>Home/Homelab/Secrets to Move.md</code> in vault. Migrate to Vaultwarden, redact notes, rotate the high-risk ones.</li>
</ul>
<h3 id="high-known-broken-verification-needed">🟠 High — known broken / verification needed<a class="headerlink" href="#high-known-broken-verification-needed" title="Permanent link">&para;</a></h3>
<ul>
<li>[x] ~~<strong>Arcane OIDC secret</strong>~~ — fixed 2026-05-23.</li>
<li>[x] ~~<strong>Backrest media-repo / video-projects</strong>~~ — <strong>all three plans succeeded 2026-05-26</strong> (media 01:30, services 01:04, video-projects 04:00). <code>video-projects-plan</code> had never completed before this. ✅</li>
<li>[x] ~~<strong>AdGuard split-horizon DNS</strong>~~ — done 2026-05-23.</li>
<li>[x] ~~<strong>WAL-G monitoring</strong>~~ — done 2026-05-23. Textfile collector (<code>/usr/local/bin/walg-metrics.sh</code>) on CT 113 emits <code>walg_last_success_timestamp_seconds</code> + <code>walg_archive_status</code> to node-exporter textfile. Prometheus alert rules deployed on CT 109: <code>WalgArchiveStale</code> (&gt;24h) + <code>WalgArchiveFailed</code>.</li>
<li>[x] ~~<strong>Zoraxy audit</strong>~~ — done 2026-05-23. All 22 routes verified; arcane updated to CT 109 backend; <code>SkipWebSocketOriginCheck</code> enabled on 13 routes; decommissioned routes noted. Missing: <code>dozzle.nuclide.systems</code> route (never created), <code>immich-tools</code>, <code>paperless</code>, <code>paperless-ai</code>. See <code>services/zoraxy.md</code>.</li>
</ul>
<h3 id="medium-incomplete-migrations-cleanup-debt">🟡 Medium — incomplete migrations / cleanup debt<a class="headerlink" href="#medium-incomplete-migrations-cleanup-debt" title="Permanent link">&para;</a></h3>
<ul>
<li>[ ] <strong>Docker disk reclaim</strong> — ~17 GB reclaimable on CT 104.</li>
<li>[ ] <strong>Dormant stacks audit</strong> — ~6 still to audit (dozzle CT 104 copy, arr-stack, qdrant, etc.). 4 decommissioned 2026-05-23.</li>
<li>[x] ~~<strong>Config-to-git fleet</strong>~~ — 8 repos as of 2026-05-24. PVE/CT 108/CT 102/HA/CT 103/CT 109/CT 113/obsidian-vault/obsidian-config. Full table in <code>infra/config-to-git.md</code>. Manual step pending: HA Terminal &amp; SSH addon <code>init_commands</code> for cron persistence.</li>
<li>[ ] <strong>D-Link hardening</strong> — admin UI at <code>http://dlink.nuclide.lan</code> (<code>192.168.1.10</code>). Trusted-host allowlist + SNMP + TLS.</li>
<li>[ ] <strong>Vaultwarden OIDC SSO</strong> — Pocket-ID client ready, env vars not yet set in <code>/opt/stacks/vaultwarden/.env</code>.</li>
<li>[ ] <strong>Infisical OIDC config</strong> — manual step in Infisical admin at <code>http://secrets.nuclide.lan:8200/admin</code> → Settings → OIDC. Client <code>b2069075-…</code>, secret <code>qsANw95zsza0_…</code>.</li>
<li>[ ] <strong>Infisical secrets migration Phase 2</strong> — import CT104 <code>.env</code> keys via <code>infisical import</code>.</li>
<li>[ ] <strong>Grafana HAOS dashboard</strong> — HA recorder reconfiguration (exclude Prometheus-covered metrics).</li>
<li>[ ] <strong>HAOS SSH key</strong> — paste nuc public key in HA terminal.</li>
<li>[ ] <strong>Obsidian config drift</strong> — 3 enabled-but-missing plugins (<code>obsidian42-brat</code>, <code>obsidian-tasks-plugin</code>, <code>tasks-caldav-sync</code>). Reinstall or remove from <code>community-plugins.json</code>. See <code>Home/Homelab/Obsidian Plugin Audit.md</code> in vault.</li>
<li>[ ] <strong>Memos Sync plugin install</strong> — config pushed to <code>obsidian-config</code>, plugin binary needs Community-Plugins install + paste of pre-baked <code>data.json</code>.</li>
<li>[ ] <strong>Immich HTTP/2 Keep-Alive</strong> — root-caused 2026-05-24. Workaround live (per-SSID LAN URL). Permanent fix: strip header at Zoraxy. <strong>Needs Zoraxy confirmation.</strong></li>
</ul>
<h3 id="planned-requires-infrastructure-or-significant-effort">🔵 Planned — requires infrastructure or significant effort<a class="headerlink" href="#planned-requires-infrastructure-or-significant-effort" title="Permanent link">&para;</a></h3>
<ul>
<li>[ ] <strong>Second NVMe</strong> — needed before rpool mirror + Postgres consolidation (CT 113). Blocks several items.</li>
<li>[ ] <strong>Infisical secrets migration</strong> — CT 112 deployed (<code>192.168.1.7:8200</code>, LAN-only). Phase 1 done. Remaining:</li>
<li><strong>Phase 2</strong>: create project <code>homelab/ct104</code>, import <code>ai/.env</code> (~55 keys) via <code>infisical import</code>, add agent sidecars to compose stacks</li>
<li><strong>Phase 3</strong>: replace hardcoded env vars in Coder <code>main.tf</code> (committed to Gitea — security risk)</li>
<li><strong>Phase 4</strong>: OIDC SSO via Pocket-ID (low priority — convenience)
See <code>services/secrets-manager.md</code>.</li>
<li>[x] ~~<strong>Consolidate syncstack → MCP gateway</strong>~~ — done 2026-05-23. <code>litellm_sync.py</code> ported from syncstack, mounted into gateway. Gateway runs <code>run_sync()</code> every 15 min (120s startup delay). <code>/etc/cron.d/syncstack</code> deleted; <code>Dockerfile.syncstack</code><code>.DECOMMISSIONED-2026-05-23</code>; <code>/opt/stacks/CLAUDE.md</code> updated.</li>
<li>[ ] <strong>ZFS ARC tuning</strong> — raise <code>zfs_arc_max</code> from 6.2 GiB → 16 GiB once CT 101 memory right-sized. See <code>infra/proxmox-state.md</code> §3.</li>
<li>[ ] <strong>Document ingestion n8n workflow</strong> — Docling MCP deployed; n8n orchestration not built. Nextcloud/Paperless → Docling → embeddings → LobeChat KB. See <code>services/doc-ingestion.md</code>.</li>
<li>[ ] <strong>ComfyUI async queue</strong> — MCP tool blocks 90300 s. Job-queue pattern: <code>generate_image()</code> returns ID; <code>get_job_status()</code> polls. See <code>services/comfyui.md</code>.</li>
<li>[ ] <strong>Additional MCP servers</strong> — Gitea ✓, Paperless ✓, Proxmox-VE ✓ (done 2026-05-23). Remaining: Karakeep (needs API key from hoarder UI), Vaultwarden, Audiobookshelf.</li>
<li>[x] ~~<strong>Arcane + Dozzle → CT 109</strong>~~ — done 2026-05-23.</li>
<li>[x] ~~<strong>crawl4ai SSE StreamConsumed</strong>~~ — resolved 2026-05-22.</li>
</ul>
<h2 id="recently-completed-2026-05-26">Recently completed (2026-05-26)<a class="headerlink" href="#recently-completed-2026-05-26" title="Permanent link">&para;</a></h2>
<ul>
<li><strong>Backrest 3-for-3 success</strong>: all plans now completing on schedule. <code>video-projects-plan</code> recovered from never-completed state.</li>
</ul>
<h2 id="recently-completed-2026-05-24">Recently completed (2026-05-24)<a class="headerlink" href="#recently-completed-2026-05-24" title="Permanent link">&para;</a></h2>
<h3 id="vault-obsidian">Vault + Obsidian<a class="headerlink" href="#vault-obsidian" title="Permanent link">&para;</a></h3>
<ul>
<li><strong>Vault dedup</strong>: <code>Work 1/</code> promoted → <code>Work/</code>, old <code>Work/</code> parked as <code>Work.stale-backup-2026-05-24/</code> (1-week safety net). Rescued unique <code>Journal/Journal.md</code> before swap. Killed dup <code>Home/BrainBox.md</code>, <code>Home/Templates/</code>, <code>Willkommen.md</code> ×2, <code>.caldav-sync/</code>.</li>
<li><strong>234 asset-link rewrites</strong> across 41 files — collapsed <code>assets/</code>, <code>../assets/</code>, <code>../../foo.pdf</code><code>.assets/…</code>. Broken links 242 → 9 (rest non-issues: <code>tel:</code>, <code>about:reader?</code>, <code>siyuan://</code>).</li>
<li><strong><code>Home/Homelab/Secrets to Move.md</code></strong> — 32 plaintext secrets inventoried.</li>
<li><strong><code>Home/Homelab/Obsidian Plugin Audit.md</code></strong> — 17 installed plugins keep/watch/re-evaluate, 3 config-drift items, 10 new candidates ranked for the stack.</li>
<li><strong><code>Home/Homelab/App Endpoint Checklist.md</code></strong> — per-service LAN + external URLs + apps-to-update list. Gotchas: clients sticking to old IP, Immich HTTP/2 Keep-Alive bug.</li>
<li><strong>Daily-note merge policy</strong>: Claude edits land in <code>Work/Journal/YYYY/MM/YYYY-MM-DD.md</code> under <code>## 🤖 Claude edits</code> (not parallel folder).</li>
<li><strong>Obsidian Git plugin</strong>: wired end-to-end against <code>fkrebs/obsidian-config</code>. Auto-commit + push every 60 min, pull on boot, PAT gitignored. Verified working.</li>
<li><strong>Streamlined-ui CSS snippet</strong> pushed to <code>obsidian-config</code> (hides ribbon icons for non-clickable plugins, compact status bar, tighter file tree).</li>
<li><strong>Memos Sync plugin config</strong> pre-pushed (binary install pending user).</li>
</ul>
<h3 id="config-to-git-fleet-expanded-to-8-repos">Config-to-git fleet expanded to 8 repos<a class="headerlink" href="#config-to-git-fleet-expanded-to-8-repos" title="Permanent link">&para;</a></h3>
<ul>
<li>New: <code>fkrebs/ct103-conf</code>, <code>fkrebs/ct109-conf</code>, <code>fkrebs/ct113-conf</code>, <code>fkrebs/home-assistant-config</code>, <code>fkrebs/obsidian-vault</code> (rolling 2-commit window), <code>fkrebs/obsidian-config</code>.</li>
<li>All daily 03:00 / 04:00. Pattern documented in <code>infra/config-to-git.md</code>.</li>
<li>Rule articulated: every host with hand-edited config must push daily.</li>
</ul>
<h3 id="networking-nuclidelan-zone">Networking — <code>*.nuclide.lan</code> zone<a class="headerlink" href="#networking-nuclidelan-zone" title="Permanent link">&para;</a></h3>
<ul>
<li><strong>30 AdGuard A-records</strong> on CT 102 — per-host (<code>pve</code>, <code>nas</code>, <code>unifi</code>, <code>dlink</code>, <code>backrest</code>, etc.) + per-service aliases (<code>immich</code>, <code>vault</code>, <code>karakeep</code>, <code>grafana</code>, <code>prometheus</code>, …).</li>
<li>Documented in <code>services/adguard-dns.md</code>.</li>
<li>Solves "client registered to old IP" gotcha — when service moves CT, edit one AdGuard rewrite instead of N apps.</li>
<li>D-Link IP captured: <code>192.168.1.10</code>.</li>
<li>Filed feedback memory: always use <code>*.nuclide.lan</code> aliases in URLs, never bare IPs.</li>
</ul>
<h3 id="homarr">Homarr<a class="headerlink" href="#homarr" title="Permanent link">&para;</a></h3>
<ul>
<li><strong>3 new boards</strong> built via SQL: <code>home</code> (morning routine, default), <code>admin</code> (by-tier), <code>command</code> (live-ops iframes + grid). Old "nuclide" board was lost when OIDC user was recreated for password reset.</li>
<li>Boards owned by <code>fkrebs@nucli.de</code>, <code>is_public=1</code>. 33 unique apps with ping status.</li>
<li>Integrations not yet wired (Proxmox / Docker / AdGuard / Gotify widgets — need tokens).</li>
</ul>
<h3 id="pocket-id">Pocket-ID<a class="headerlink" href="#pocket-id" title="Permanent link">&para;</a></h3>
<ul>
<li><strong>LAN callback URLs added</strong> for Homarr, Grafana, Infisical, Proxmox VE so OIDC works via both bare-IP and <code>.nuclide.lan</code> alias paths.</li>
</ul>
<h3 id="other">Other<a class="headerlink" href="#other" title="Permanent link">&para;</a></h3>
<ul>
<li><strong>Immich Android upload bug</strong> diagnosed: HTTP/2 + <code>Keep-Alive</code> header conflict. Workaround live (per-SSID LAN URL). Permanent fix pending Zoraxy header strip.</li>
<li><strong>Nexa #1 filed</strong> at https://git.nuclide.systems/fkrebs/nexa/issues/1 — 9 design patterns from Obsidian + Claude session as input for Nexa Phase 12.</li>
<li><strong>Wi-Fi SSID captured</strong>: <code>nuclide</code>. Used for per-network app routing (Immich, HA Companion).</li>
</ul>
<h2 id="recently-completed-2026-05-23-session-continued-4">Recently completed (2026-05-23, session continued ×4)<a class="headerlink" href="#recently-completed-2026-05-23-session-continued-4" title="Permanent link">&para;</a></h2>
<ul>
<li><strong>Docs consistency pass</strong>: zoraxy.md, arcane.md, ct-inventory.md, portmap.md, proxmox-memory-audit.md, mcp-gateway.md, RESUME.md all updated to reflect 2026-05-23 state.</li>
<li><strong>Wetty deployed</strong> on CT 109 (:4090, LAN-only). <code>jump-menu.sh</code> on nuc → SSH jump menu to all 10 hosts.</li>
<li><strong>MCP servers added</strong>: gitea, paperless, proxmox (read-only PVEAuditor role). Total: 30 servers.</li>
<li><strong>Loki dashboard fixed</strong>: K8s labels replaced with Docker labels in 14 places.</li>
<li><strong>WAL-G monitoring</strong>: textfile collector on CT 113 + Prometheus alert rules on CT 109.</li>
<li><strong>CT 103 RAM</strong>: 2 GB → 4 GB + 1 GB swap (Backrest OOM fix for 822 GB initial backup).</li>
<li><strong>Zoraxy WS</strong>: <code>SkipWebSocketOriginCheck</code> enabled on 13 routes. Arcane upstream corrected to CT 109.</li>
<li><strong>CT 104 cleanup</strong>: daytona, homepage, proxy, streamio decommissioned.</li>
<li><strong>Paperless-ngx</strong>: USERMAP_UID=997 + file permissions fixed, container stable.</li>
</ul>
<h2 id="recently-completed-2026-05-23-session-continued-3">Recently completed (2026-05-23, session continued ×3)<a class="headerlink" href="#recently-completed-2026-05-23-session-continued-3" title="Permanent link">&para;</a></h2>
<ul>
<li><strong>Homarr board deployed</strong>: 6 category sections (AI, Monitoring, Files, Dev, Home, Identity &amp; Admin), 27 apps with ping-based status, Mainsail included in Dev. Fixed schema: <code>x_offset</code>/<code>y_offset</code> on section rows + paired empty sections (y=0 initial, y=1/2 per category). Board <code>nuclide</code> set as home board.</li>
<li><strong>Arcane environments fixed</strong>: deleted stale shared-token environments; created 6 unique edge environments (shepard, docker, nextcloud, id, dev, secrets) via API with <code>useApiKey=true</code>. Each agent updated with unique token. All 8 environments online.</li>
<li><strong>Arcane API key seeded</strong>: <code>ADMIN_STATIC_API_KEY</code> from compose was never seeded (DB pre-existed). Inserted via argon2id hash. Key <code>arc_d3357a65</code> now functional for automation.</li>
<li><strong>Infisical SITE_URL fixed</strong>: changed from <code>https://secrets.nuclide.systems</code> to <code>http://192.168.1.7:8200</code> (LAN-only, no Zoraxy route).</li>
<li><strong>Infisical Pocket-ID client created</strong>: client <code>b2069075-ede2-4251-ad1f-9a62e6a188b3</code>, callback <code>http://192.168.1.7:8200/api/v1/sso/oidc/callback</code>. Manual OIDC config entry still needed in Infisical admin UI.</li>
</ul>
<h2 id="recently-completed-2026-05-23-session-continued-2">Recently completed (2026-05-23, session continued ×2)<a class="headerlink" href="#recently-completed-2026-05-23-session-continued-2" title="Permanent link">&para;</a></h2>
<ul>
<li><strong>PVE LXC startup order fixed</strong>: CT103/104/105/112/113 had no startup order. Set: CT113=4, CT112=6, CT104=7, CT103=8, CT105=9. Full deterministic boot sequence now in place. Also enabled CT109 onboot=1 (was missing).</li>
<li><strong>KSM enabled on PVE host</strong>: kernel samepage merging active + persisted via <code>ksm-enable.service</code>. Zero-cost memory deduplication across LXC containers.</li>
<li><strong>5-minute critical watchdog deployed</strong>: <code>homelab-health-quick.timer</code> on nuc; <code>QUICK=1</code> mode checks LXC status + critical containers every 5 min. Auto-starts stopped LXCs, notifies Gotify for HAOS KVM issues.</li>
<li><strong>PVE backlog issues filed</strong>: <code>fkrebs/docs</code> #2 (NFS v3→v4), #3 (ZFS ARC 16 GiB), #4 (hugepages for KVM).</li>
</ul>
<h2 id="recently-completed-2026-05-23-session-continued">Recently completed (2026-05-23, session continued)<a class="headerlink" href="#recently-completed-2026-05-23-session-continued" title="Permanent link">&para;</a></h2>
<ul>
<li><strong>HAOS KVM OOM root-caused and fixed</strong>: karakeep_chrome on CT 104 triggered host OOM → killed HAOS KVM twice. Applied: <code>shm_size: '512m'</code> to chrome, <code>oom_score_adj=-300</code> on KVM PID, systemd timer <code>protect-haos-kvm.timer</code> (every 5 min) for persistence.</li>
<li><strong>Arcane + Dozzle migrated to CT 109</strong>: servers on CT 109 (:10002, :10001). Headless agents deployed on CT 101, 104, 105, 110, 111, 112, 113. Zoraxy route updated. docs-server also on CT 109 (:13080).</li>
<li><strong>Homarr + Grafana OIDC wired</strong>: clients created via Pocket-ID API (no manual UI steps). Homarr client <code>63a94e30</code>, Grafana client <code>92d987d5</code> (PKCE). Both SSO-active.</li>
<li><strong>n8n flows tracked in Gitea</strong>: repo <code>fkrebs/n8n-flows</code> with daily sync cron (CT 104, 03:30). 10 automation ideas filed as Gitea issues. Interim health check bash/systemd on nuc (issue #1 = migrate to n8n).</li>
<li><strong>CT 104 ai repo cleaned</strong>: <code>lobehub/data/</code> untracked from git, <code>.gitignore</code> fixed, litellm-config + mcp-gateway changes committed.</li>
<li><strong>zoraxy-conf repo</strong>: arcane proxy update committed and pushed (CT 108).</li>
</ul>
<h2 id="recently-completed-2026-05-23">Recently completed (2026-05-23)<a class="headerlink" href="#recently-completed-2026-05-23" title="Permanent link">&para;</a></h2>
<ul>
<li><strong>Config-to-git crons</strong>: scripts + daily 03:00 crons deployed on CT 108 (Zoraxy → <code>zoraxy-conf</code>), CT 102 (AdGuard → <code>adguard-conf</code>), PVE (rsync <code>/etc/pve</code><code>pve-conf</code>). Force-push. All three verified with initial push.</li>
<li><strong>Syncstack → MCP gateway</strong>: <code>litellm_sync.py</code> (ported from syncstack.py) mounted into gateway container. <code>_litellm_sync_loop()</code> runs every 15 min in gateway's asyncio loop. Cron <code>/etc/cron.d/syncstack</code> deleted. <code>Dockerfile.syncstack</code> decommissioned. <code>/opt/stacks/CLAUDE.md</code> updated.</li>
</ul>
<h2 id="recently-completed-session-continued-2-2026-05-22">Recently completed (session continued ×2, 2026-05-22)<a class="headerlink" href="#recently-completed-session-continued-2-2026-05-22" title="Permanent link">&para;</a></h2>
<ul>
<li><strong>crawl4ai MCP fixed</strong>: was returning 404 on <code>/mcp</code> (streamable-HTTP). Current 0.8.6 image already has MCP over SSE at <code>/mcp/sse</code>. Added SSE transport support to <code>mcp-gateway/server.py</code>: per-request SSE round-trip with auto-initialize handshake; <code>transport: sse</code> in hardcoded SERVERS + config.json. Gateway health now shows crawl4ai ok; lobe-sync shows 27/27 servers.</li>
<li><strong>syncstack cron fixed</strong>: missing <code>cd /opt/stacks/ai &amp;&amp;</code> prefix caused "no configuration file" every 15 min since ~May 18. Fixed. Manual run confirmed 60 models including 5 Claude models; LobeChat recreated.</li>
</ul>
<h2 id="recently-completed-session-continued-2026-05-22">Recently completed (session continued, 2026-05-22)<a class="headerlink" href="#recently-completed-session-continued-2026-05-22" title="Permanent link">&para;</a></h2>
<ul>
<li><strong>claude-max-bridge <code>/v1/responses</code> endpoint</strong>: implemented OpenAI Responses API with <code>previous_response_id</code> chaining. Root cause of "session already in use": Claude CLI leaves session JSONL files in an un-resumable "dequeued" state after each <code>--print</code> run. Fix: maintain conversation history server-side as formatted text; inject into system prompt for continuations; always use <code>--no-session-persistence</code>. Also fixed: assistant turns in <code>--input-format stream-json</code> require <code>content</code> as array-of-blocks not string (JS error otherwise). Assistant content array format also fixed in <code>_parse_messages</code> / <code>_parse_responses_input</code>.</li>
<li><strong>LiteLLM pass-through for <code>/v1/responses</code></strong>: added <code>pass_through_endpoints</code> entry in <code>/opt/stacks/ai/litellm-config/config.yaml</code><code>http://claude-max-bridge:8000/v1/responses</code>. LiteLLM appends its token hash to the response <code>id</code>, so <code>previous_response_id</code> chaining only works when calling the bridge directly (not through LiteLLM).</li>
</ul>
<h2 id="recently-completed-this-session-2026-05-22">Recently completed (this session, 2026-05-22)<a class="headerlink" href="#recently-completed-this-session-2026-05-22" title="Permanent link">&para;</a></h2>
<ul>
<li><strong>Pocket-ID backup</strong>: pre-hook on CT 103 runs <code>pocket-id export</code> + scp keys → UNAS staging; <code>services-backup-plan</code> snapshots → jottacloud. Verified.</li>
<li><strong>Stale NFS vaultwarden dir deleted</strong>: <code>/mnt/pve/unas/services/vaultwarden/</code> removed.</li>
<li><strong>Nextcloud CIFS → NFS</strong>: crash-loop fixed; CT 105 mp0 migrated from <code>/mnt/pve/unas_smb</code> to <code>/mnt/pve/unas</code>; CIFS fstab entry removed.</li>
<li><strong>Vaultwarden → local zfs</strong>: <code>/mnt/pve/unas/services/vaultwarden</code><code>/opt/stacks/vaultwarden/data</code>; stale <code>db.sqlite3</code> deleted; DB already on CT 113 postgres.</li>
<li><strong>WAL-G fixed</strong>: <code>immich_postgres</code> and <code>lobe-postgres</code> backups now succeed. Fixed: missing <code>-u postgres</code>, missing data path, <code>set -e</code> abort, dead <code>shared-postgres</code> reference.</li>
<li><strong>ComfyUI <code>--async-offload</code> removed</strong>: caused CPU fallback + pure-noise output on GGUF img2img with XPU.</li>
<li><strong>apps/ decommissioned</strong>: dead duplicate compose files in <code>/opt/stacks/apps/</code> renamed <code>.DECOMMISSIONED-2026-05-22</code>.</li>
<li><strong>Docs consolidated</strong>: storage.md, volumes.md, homelab-architecture.md, proxmox-state.md, proxmox-memory-audit.md, ct-inventory.md, README.md all reconciled.</li>
</ul>
<h2 id="key-system-state">Key system state<a class="headerlink" href="#key-system-state" title="Permanent link">&para;</a></h2>
<table>
<thead>
<tr>
<th>Host</th>
<th>IP</th>
<th>Role</th>
</tr>
</thead>
<tbody>
<tr>
<td>nuc (PVE)</td>
<td>192.168.1.20</td>
<td>Proxmox host — SSH gateway to all CTs; jump-menu.sh</td>
</tr>
<tr>
<td>CT 109 ops</td>
<td>192.168.1.8</td>
<td>Monitoring — Prometheus + Grafana + Loki + Arcane + Dozzle + Homarr + Wetty</td>
</tr>
<tr>
<td>CT 104 docker</td>
<td>192.168.1.40</td>
<td>Main Docker host — AI/ML, media, ~65 containers</td>
</tr>
<tr>
<td>CT 113 db</td>
<td>192.168.1.6</td>
<td>Shared Postgres 17 + WAL-G → Garage S3 (cron 02:00)</td>
</tr>
<tr>
<td>CT 110 id</td>
<td>192.168.1.5</td>
<td>Pocket-ID OIDC IdP</td>
</tr>
<tr>
<td>CT 103 backrest</td>
<td>192.168.1.3</td>
<td>Backrest — jottacloud via rclone; UNAS at <code>/mnt/pve/unas</code></td>
</tr>
<tr>
<td>CT 111 dev</td>
<td>192.168.1.42</td>
<td>Coder + Gitea</td>
</tr>
<tr>
<td>CT 108 zoraxy</td>
<td>192.168.1.4</td>
<td>Reverse proxy + ACME — <strong>always confirm before changes</strong></td>
</tr>
</tbody>
</table>
<h2 id="constraints-to-remember">Constraints to remember<a class="headerlink" href="#constraints-to-remember" title="Permanent link">&para;</a></h2>
<ul>
<li>Zoraxy (CT 108): always get explicit user confirmation before any config change.</li>
<li>Infisical (CT 112): LAN-only, no Zoraxy route — must not be internet-exposed.</li>
<li>CT 104 has a separate agent reconciling compose files — rename decommissioned files (don't just stop), update <code>/opt/stacks/CLAUDE.md</code>.</li>
<li>ComfyUI container limit: 24 G. Do not raise without measuring host impact.</li>
<li>Pocket-ID is SQLite-only — no Postgres migration possible.</li>
<li>Use <code>*.nuclide.lan</code> aliases when presenting URLs to the user (never bare IPs). Wi-Fi SSID is <code>nuclide</code>.</li>
<li>Vault edits append to <code>Work/Journal/YYYY/MM/YYYY-MM-DD.md</code> under <code>## 🤖 Claude edits</code>; never create a parallel folder.</li>
</ul>
</article>
</div>
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
</div>
<button type="button" class="md-top md-icon" data-md-component="top" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8z"/></svg>
Back to top
</button>
</main>
<footer class="md-footer">
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-copyright">
Made with
<a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
Material for MkDocs
</a>
</div>
</div>
</div>
</footer>
</div>
<div class="md-dialog" data-md-component="dialog">
<div class="md-dialog__inner md-typeset"></div>
</div>
<script id="__config" type="application/json">{"annotate": null, "base": "..", "features": ["navigation.tabs", "navigation.sections", "navigation.expand", "navigation.top", "search.highlight", "search.suggest", "content.code.copy"], "search": "../assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
<script src="../assets/javascripts/bundle.79ae519e.min.js"></script>
</body>
</html>