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 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:
- 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
- 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
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:
- 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