diff --git a/deploy/server/docker-compose.yml b/deploy/server/docker-compose.yml index 0b2388e..ebfe528 100644 --- a/deploy/server/docker-compose.yml +++ b/deploy/server/docker-compose.yml @@ -87,8 +87,9 @@ services: NETWORKS: "1" # inspect/attach (docker run needs the bridge network) POST: "1" GET: "1" - # On a rootless-Docker host set DOCKER_SOCKET=/run/user//docker.sock in .env - # (setup.sh writes .env; the rootful default is /var/run/docker.sock). + # On a rootless-Docker host this has to be DOCKER_SOCKET=/run/user//docker.sock in .env: + # setup.sh finds it and writes it (also into a kept .env). The rootful default is + # /var/run/docker.sock; on a rootless host that is another daemon and the proxy answers 503. volumes: - ${DOCKER_SOCKET:-/var/run/docker.sock}:/var/run/docker.sock:ro volumes: diff --git a/deploy/server/setup.sh b/deploy/server/setup.sh index 38d0a99..ae45bf8 100755 --- a/deploy/server/setup.sh +++ b/deploy/server/setup.sh @@ -126,6 +126,16 @@ lan_ip() { [ -z "$a" ] && a=$(hostname -I 2>/dev/null | awk '{print $1}') printf '%s' "$a" } +# The socket docker-socket-proxy has to mount: the one of the daemon this script runs compose +# against. Only rootless Docker needs it spelled out (/run/user//docker.sock): there the +# compose default /var/run/docker.sock is another daemon (the root one, or none) and every Docker +# call of the brain comes back 503. Prints nothing when the default is right. +rootless_socket() { + docker info --format '{{json .SecurityOptions}}' 2>/dev/null | grep -q 'name=rootless' || return 0 + local h=${DOCKER_HOST:-} + [ -z "$h" ] && h=$(docker context inspect --format '{{.Endpoints.docker.Host}}' 2>/dev/null) + case "$h" in unix://*) printf '%s' "${h#unix://}" ;; esac +} # ---------- 0. this server ---------- AT=0; header; card_open "檢查這台伺服器" @@ -280,9 +290,21 @@ if [ "${SKIP:-0}" != 1 ]; then fi fi +# Rootless Docker: pin its socket in .env, whether .env was just written or kept from an earlier +# setup (one made before docker-socket-proxy came along has no DOCKER_SOCKET). +SOCK=$(rootless_socket) +if [ -n "$SOCK" ]; then + if ! grep -qxF "DOCKER_SOCKET='$SOCK'" .env; then + (umask 077; { grep -v '^DOCKER_SOCKET=' .env; printf "DOCKER_SOCKET='%s'\n" "$SOCK"; } >.env.new) \ + && mv .env.new .env + fi + export DOCKER_SOCKET=$SOCK +fi + # ---------- 4. start ---------- AT=3; header; card_open "啟動" ok "寫好設定(.env、Caddyfile)" +[ -n "$SOCK" ] && ok "Docker 是 rootless:大腦經由 $SOCK 管 Bot 的電腦" if [ $DRY = 1 ]; then warn "試跑(--dry-run):沒有啟動。要啟動:docker compose up -d --build" card_close; exit 0 diff --git a/docs/plan-2026-11-improvements.md b/docs/plan-2026-11-improvements.md index 5ae9947..b09bcab 100644 --- a/docs/plan-2026-11-improvements.md +++ b/docs/plan-2026-11-improvements.md @@ -52,7 +52,10 @@ - README/docs 加 `SECURITY.md`+威脅模型章節:哪些金鑰存哪裡(vault 的 AES-GCM+keychain)、relay 只存雜湊、box 的隔離層(gVisor)、docker.sock 收斂後的能力面、prompt injection 的防線(見 S3)、「Bot 動過我電腦什麼」的稽核面(A1)。 - ✅ 完成標準: SECURITY.md + `security@` 通報管道 + GitHub/Gitea security advisory 開啟。 -## P6. 記憶升級:第二個大腦(依賴 P4) 🔶 第一步 2026-11:SQLite memories+FTS5(trigram;中文二字窗計分)檢索 top-14 進 prompt(不再全量注入);每回合自動寫事件行(問→答)跨月可查;remember/forget/UI 同步索引。第二步:Ollama 本機 embedding 進同表、Khoj 式文件索引 +## P6. 記憶升級:第二個大腦(依賴 P4) ✅ 2026-11 完成 + +- **第一步**:SQLite memories+FTS5(trigram;中文二字窗計分)top-14 進 prompt(不再全量注入);每回合自動寫事件行(問→答)跨月可查;remember/forget/UI 同步索引 +- **第二步**:本機 embedding(Ollama `/api/embed`,模型自動偵測 bge-m3/nomic…;無 Ollama=純關鍵字照常運作);記憶檢索改混合式(FTS+二字窗+cosine,RRF 合併);**文件書架**:設定可加資料夾(預設 文件),md/txt/csv/程式碼切塊入 SQLite+FTS、mtime 增量、刪除即除名;新工具 `search_documents`(唯讀免核准);背景執行緒慢活,回合永不等 embedding;設定 › 一般:語意搜尋開關+資料夾清單 - 現況:`src/memory.rs` 每 Bot 200 條×500 字,無 embedding、無檢索——對照 Letta/Khoj 是最明顯短板。 - 做法: 1. 離線 embedding:優先本機(Ollama 路徑已有;小模型如 bge-m3/qwen3-embedding),雲端 provider 当備援。 @@ -193,7 +196,7 @@ | M2(第 3–5 週) | C2 AX 直寫、H1/H3 工具收斂+瘦身、S4 egress、P8 CI | v12 bench:步數 −30%、編號點錯歸零 | | M3(第 6–8 週) | C3 高層工具、C4 diff、C7 狀態碼、S3 injection 防線+紅隊進 CI | T8 ≤2 回合;紅隊洩漏 0 | | M4(第 9–12 週) ✅ | P2 英文+demo、S2 2FA、S5 稽核時間軸、P4 SQLite(第一步) | 2026-11 完成;demo 影像、bench 夜間回歸(需機器)待補 | -| M4.5 ✅ | 手機 2FA/裝置清單、H2 瀏覽器單一新工具(25→2 schema)、H3(輕)、P6 第一步(記憶檢索+事件日誌) | 2026-11 完成;embedding/文件索引為 P6 第二步 | +| M4.5 ✅ | 手機 2FA/裝置清單、H2 瀏覽器單一新工具(25→2 schema)、H3(輕)、P6 記憶+事件日誌+本機 embedding+文件書架(全部完成) | 2026-11 完成 | | M5(第 13 週起) | P6 記憶/RAG、P7 技能 registry、C6 意圖表、C5 小錢、C8 重播、C9 Windows | Khoj/Letta 對照測試;技能安裝量開始計量 | 每階段結束以 `bench/computer-use` 固定題組+新增題(多選單 App、長表單、注入紅隊)做前後對照,結果續寫進 `bench/computer-use/README.md` 的版本記錄。