Перейти к содержанию

v1.0.1 Reliability Hardening — Implementation Plan

For agentic workers: Execute inline — batch with checkpoints.

Goal: Fix all reliability issues in opencode_initializer v1.0.0: ensure services auto-start after reboot, verify all MCP servers work, update component versions, make the system truly "batteries included".

Architecture: Fix systemd service definitions for Ollama, Open WebUI, Muninn. Update MCP server versions in 12-mcp-lsp.sh. Regenerate opencode.json with bun binary paths. Add post-install verification that services actually start. Implement health-check improvements.

Tech Stack: Bash 4.0+, systemd (user), Bun, npm, OpenCode

Global Constraints

  • No secrets committed
  • bash -n passes on all modified files
  • All changes backward-compatible
  • Service files use %h for home directory (portable)
  • Muninn must auto-start with ChromaDB dependency
  • MCP servers prefer bun binary paths over npx for cold start

Task 1: Create Open WebUI systemd User Service

Files: - Create: src/lib/22-webui-service.sh (new module for Open WebUI service setup) - Modify: setup.sh (add step_skip step_webui)

Interfaces: - Consumes: helpers.sh (_sudo, log), 00-core.sh (step_done, step_mark) - Produces: ~/.config/systemd/user/open-webui.service, enabled and started

  • Step 1: Write the service file template
# open-webui.service — User-level systemd service for Open WebUI
cat > ~/.config/systemd/user/open-webui.service << 'EOF'
[Unit]
Description=Open WebUI — LLM Chat Interface
After=network.target ollama.service
Wants=ollama.service

[Service]
Type=simple
Environment=OLLAMA_BASE_URL=http://127.0.0.1:11434
ExecStart=%h/.local/bin/open-webui serve --host 127.0.0.1 --port 3000
Restart=on-failure
RestartSec=5

[Install]
WantedBy=default.target
EOF
  • Step 2: Enable and start the service
systemctl --user daemon-reload
systemctl --user enable open-webui.service
systemctl --user start open-webui.service
  • Step 3: Verify service is active
systemctl --user is-active open-webui.service
# Expected: active
curl -s http://127.0.0.1:3000 | head -5
# Expected: HTML page
  • Step 4: Create the module 22-webui-service.sh
#!/usr/bin/env bash
# ============================================================================
# Open WebUI systemd service setup
set -euo pipefail

_step_skip step_webui && return 0

section "Open WebUI: systemd service"

if ! command -v open-webui &>/dev/null; then
  warn "Open WebUI binary not found — install it first (pip install open-webui)"
  return 0
fi

mkdir -p ~/.config/systemd/user

cat > ~/.config/systemd/user/open-webui.service << 'SVC'
[Unit]
Description=Open WebUI — LLM Chat Interface
After=network.target
Wants=network.target

[Service]
Type=simple
Environment=OLLAMA_BASE_URL=http://127.0.0.1:11434
ExecStart=%h/.local/bin/open-webui serve --host 127.0.0.1 --port 3000
Restart=on-failure
RestartSec=5

[Install]
WantedBy=default.target
SVC

systemctl --user daemon-reload
systemctl --user enable open-webui.service
systemctl --user start open-webui.service 2>/dev/null || true

step_mark "step_webui"
log "Open WebUI systemd service installed and started"
  • Step 5: Add to setup.sh

Add after the rag step in setup.sh (~line 291):

_step_skip step_webui     || source "$SCRIPT_DIR/src/lib/22-webui-service.sh"

  • Step 6: Commit
git add src/lib/22-webui-service.sh setup.sh
git commit -m "feat: add Open WebUI systemd user service module"

Task 2: Fix Ollama — Ensure Proper User-Level Service

Files: - Modify: src/lib/16-llm.sh (add user-level ollama service setup)

Interfaces: - Consumes: helpers.sh - Produces: ~/.config/systemd/user/ollama.service, running ollama

  • Step 1: Check current Ollama installation

Snap-based Ollama runs as root — this is problematic for Open WebUI integration. The fix is to add a user-level systemd service that wraps the snap binary or use the native install.

# Check if Ollama is installed via snap
if snap list ollama &>/dev/null; then
  OLLAMA_BIN="/snap/bin/ollama"
else
  OLLAMA_BIN="$(which ollama 2>/dev/null || echo '')"
fi
  • Step 2: Add systemd user service generation to 16-llm.sh

After the Ollama install section, add:

# ── Ollama user-level systemd service ──────────────────────────
if command -v ollama &>/dev/null; then
  mkdir -p ~/.config/systemd/user

  cat > ~/.config/systemd/user/ollama.service << 'SVC'
[Unit]
Description=Ollama — Local LLM Runtime
After=network.target

[Service]
Type=simple
Environment=OLLAMA_HOST=127.0.0.1:11434
ExecStart=/snap/bin/ollama serve
Restart=on-failure
RestartSec=5

[Install]
WantedBy=default.target
SVC

  systemctl --user daemon-reload
  systemctl --user enable ollama.service
  systemctl --user start ollama.service 2>/dev/null || true
  log "Ollama user systemd service installed"
fi
  • Step 3: Update ChromaDB service to depend on network

Modify the ChromaDB service creation in 13-chromadb.sh to add proper After= dependency:

After=network.target
  • Step 4: Verify all three services chain
systemctl --user is-active chromadb    # Expected: active
systemctl --user is-active ollama      # Expected: active
systemctl --user is-active open-webui  # Expected: active
systemctl --user list-dependencies chromadb
  • Step 5: Commit
git add src/lib/16-llm.sh src/lib/13-chromadb.sh
git commit -m "fix: add Ollama user systemd service, fix service dependencies"

Task 3: Verify Muninn and Memory Chain

Files: - Research only — no code changes unless issue found

Interfaces: - Verifies: ChromaDB → Muninn → MemoryLayer MCP chain

  • Step 1: Check Muninn installation
which muninn 2>/dev/null || echo "Muninn not found as binary"
ls ~/.local/bin/muninn* 2>/dev/null || echo "No muninn in ~/.local/bin"
  • Step 2: Test ChromaDB API
curl -s http://127.0.0.1:8000/api/v1/heartbeat 2>&1
# Expected: {"nanosecond heartbeat": ...}
  • Step 3: Check memorylayer MCP server can start
timeout 5 ~/.bun/bin/memorylayer-mcp 2>&1 || true
# Expected: starts without errors (may timeout — that's fine)
  • Step 4: If Muninn not installed, install it
# Check if it's a skill vs standalone tool
ls ~/.config/opencode/skills/memory-read/ 2>/dev/null
ls ~/.config/opencode/skills/memory-write/ 2>/dev/null

Muninn/Memory is typically an OpenCode skill, not a standalone binary. The ChromaDB server provides the vector database backend. The memorylayer-mcp server provides the MCP interface. If both are running, Muninn effectively works.

  • Step 5: Document the memory chain

No code changes needed. The chain is: 1. ChromaDB (port 8000) — vector database backend 2. MemoryLayer MCP (bun binary) — MCP interface for memory operations 3. Muninn skills (memory-read, memory-write) — OpenCode skills that use MemoryLayer MCP

Add this to health check output.


Task 4: Update MCP Server Versions

Files: - Modify: src/lib/12-mcp-lsp.sh (update version pins)

Interfaces: - Consumes: helpers.sh (_npm_install) - Produces: updated MCP packages

  • Step 1: Check latest MCP server versions
# Check the latest releases
npm view @modelcontextprotocol/server-everything version
npm view @modelcontextprotocol/server-memory version
npm view @modelcontextprotocol/server-filesystem version
npm view @modelcontextprotocol/server-sequential-thinking version
npm view @modelcontextprotocol/server-redis version
npm view mcp-server-git version
npm view mcp-server-time version
npm view mcp-server-fetch version
npm view mcp-server-sqlite version
  • Step 2: Update version strings in 12-mcp-lsp.sh
# Current versions in file → Latest versions from npm
# Replace old version strings with new ones
sed -i 's/@modelcontextprotocol\/server-memory@[^"]*/@modelcontextprotocol\/server-memory@2026.1.26/g' src/lib/12-mcp-lsp.sh
# ... etc for each MCP server
  • Step 3: Verify all bun binary paths exist or are installable
for pkg in agent-browser-mcp-server agentic-tools-mcp codegraph loopsense mcp-server-filesystem mcp-server-github mcp-server-postgres mcp-server-sequential-thinking memorylayer-mcp playwright-mcp c7-mcp-server; do
  if [ -f ~/.bun/bin/$pkg ]; then
    echo "OK: $pkg"
  else
    echo "MISSING: $pkg"
  fi
done
  • Step 4: Commit
git add src/lib/12-mcp-lsp.sh
git commit -m "chore: update MCP server versions to 2026.1.26"

Task 5: Fix opencode.json Generation — Use Bun Paths

Files: - Modify: src/lib/18-opencode-json.sh (ensure local_cmd uses bun paths)

Interfaces: - Consumes: bun installation - Produces: opencode.json with absolute bun binary paths

  • Step 1: Verify current local_cmd function

Check that local_cmd() in 18-opencode-json.sh generates paths like:

"/home/$USER/.bun/bin/mcp-server-github"
instead of:
"npx", "-y", "@modelcontextprotocol/server-github"

  • Step 2: Fix any npx references

If any MCP server command still uses npx, replace with bun binary path.

  • Step 3: Regenerate opencode.json and verify
bash setup.sh --fix-config
python3 -c "import json; json.load(open(os.path.expanduser('~/.config/opencode/opencode.json')))" && echo "Valid JSON"
  • Step 4: Commit
git add src/lib/18-opencode-json.sh
git commit -m "fix: ensure MCP servers use bun binary paths for cold start"

Task 6: Health Check Improvements — Service Status

Files: - Modify: src/modes/health.sh (add service status checks)

Interfaces: - Consumes: systemctl - Produces: health report with service status

  • Step 1: Add service status section to health check

Add after existing checks:

echo -e "\n${CYAN}── Services (systemd user) ──${NC}"
for svc in chromadb ollama open-webui opencode-update.timer; do
  if systemctl --user is-active "$svc" &>/dev/null; then
    echo -e "  ${GREEN}✓${NC} $svc"
  else
    echo -e "  ${RED}✗${NC} $svc (inactive)"
  fi
done
  • Step 2: Add memory chain health check
echo -e "\n${CYAN}── Memory Chain ──${NC}"
# ChromaDB
if curl -s http://127.0.0.1:8000/api/v1/heartbeat &>/dev/null; then
  echo -e "  ${GREEN}✓${NC} ChromaDB heartbeat"
else
  echo -e "  ${RED}✗${NC} ChromaDB unreachable"
fi

# Muninn (check skills exist)
for skill in memory-read memory-write; do
  if [ -f ~/.config/opencode/skills/$skill/SKILL.md ]; then
    echo -e "  ${GREEN}✓${NC} $skill skill"
  else
    echo -e "  ${YELLOW}⚠${NC} $skill skill not found"
  fi
done

# MemoryLayer MCP
if [ -f ~/.bun/bin/memorylayer-mcp ]; then
  echo -e "  ${GREEN}✓${NC} memorylayer-mcp binary"
else
  echo -e "  ${RED}✗${NC} memorylayer-mcp missing"
fi
  • Step 3: Add MCP binary count
echo -e "\n${CYAN}── MCP Binaries (~/.bun/bin/) ──${NC}"
MCP_COUNT=$(ls ~/.bun/bin/ 2>/dev/null | grep -v -E '^(bun|bunx)$' | wc -l)
echo -e "  ${GREEN}✓${NC} $MCP_COUNT MCP binaries installed"
  • Step 4: Commit
git add src/modes/health.sh
git commit -m "feat: add service status and memory chain to health checks"

Task 7: Final Verification — Run Everything

Files: - None (verification only)

  • Step 1: Syntax check all modified files
for f in setup.sh src/lib/*.sh src/modes/*.sh; do bash -n "$f" && echo "OK: $f" || echo "FAIL: $f"; done
# Expected: all OK
  • Step 2: Rebuild documentation
source .venv-docs/bin/activate && mkdocs build 2>&1 | grep -E "ERROR|built"
# Expected: no ERROR, "Documentation built in X.XX seconds"
  • Step 3: Verify all services can start
systemctl --user daemon-reload
systemctl --user restart chromadb
sleep 2
systemctl --user is-active chromadb
curl -s http://127.0.0.1:8000/api/v1/heartbeat
systemctl --user start ollama 2>/dev/null || echo "ollama via snap — OK if running"
systemctl --user start open-webui 2>/dev/null || echo "open-webui service installed"
  • Step 4: Verify opencode.json validity
python3 -c "
import json
with open('$HOME/.config/opencode/opencode.json') as f:
    c = json.load(f)
mcps = c.get('mcp', {})
print(f'MCP servers: {len(mcps)}')
print(f'Plugins: {len(c.get(\"plugin\", []))}')
print(f'LSP servers: {len(c.get(\"lsp\", {}))}')
print(f'Agents: {len(c.get(\"agent\", {}))}')
print('openclode.json VALID')
"
  • Step 5: Final commit
git add -A
git status
git commit -m "v1.0.1: reliability hardening — services, MCP versions, health checks"