Files
pi-agent-config/scenarios/curator/backend/systemd/curator.service
T
Kai 35af26c794 feat(curator): vendor the backend application under scenarios/curator/backend
The curator app (Python backend, tests, systemd units, config, scripts) now lives in this repo under scenarios/curator/backend, exported from the standalone checkout's tracked tree (.pi mirror, venv and caches excluded). 149 unit tests pass from the new location; _SHARED_LIB and eval GOLDEN_DIR resolve unchanged. History not preserved per decision.

verify-no-secrets: the ASSIGN heuristic now requires the value to carry entropy (a digit or uppercase letter), so vendored Python kwargs like token=extraction_token no longer false-positive while real base64/hex/random secrets still trip it.
2026-08-30 07:54:39 -07:00

78 lines
3.0 KiB
Desktop File

[Unit]
Description=Curator personal media library
Wants=network-online.target
After=network-online.target
[Service]
Type=simple
WorkingDirectory=/home/claw/pi-workspaces/curator
Environment=PYTHONPATH=/home/claw/pi-workspaces/curator
Environment=CURATOR_PI_WORKSPACE=/home/claw/pi-workspaces/curator
Environment=CURATOR_PI_SESSION_DIR=/home/claw/.local/share/pi-curator/sessions
Environment=CURATOR_PI_MODEL=zenmux/openai/gpt-5.6-luna
Environment=CURATOR_PI_THINKING=high
Environment=CURATOR_PI_FALLBACK_MODEL=zenmux/x-ai/grok-4.6
Environment=CURATOR_PI_TIMEOUT_SECONDS=120
Environment=CURATOR_WECHAT_ARTICLE_BASE_URL=http://192.168.50.145:8091
EnvironmentFile=/home/claw/.config/curator/curator.env
ExecStart=/usr/bin/python3 -m curator serve
Restart=on-failure
RestartSec=5
TimeoutStartSec=60
TimeoutStopSec=20
# --- filesystem -------------------------------------------------------------
# The whole hierarchy is read-only apart from the paths listed below. Verified
# with systemd-run before being applied: the database, library, staging, backup
# and cover directories are writable and pi starts cleanly.
ProtectSystem=strict
ProtectHome=read-only
ReadWritePaths=/home/claw/.local/share/curator
ReadWritePaths=/mnt/truenas/multimedia/books
ReadWritePaths=/mnt/truenas/multimedia/curator
ReadWritePaths=/home/claw/.local/share/pi-curator
# pi takes a lock beside ~/.pi/agent/settings.json on startup. With a read-only
# home it cannot, and then reports the settings file as invalid and ignores it --
# which would silently discard the agent's configuration.
ReadWritePaths=/home/claw/.pi
# The agent's own prompt and launch contract are read-only to the service that
# runs it, so a compromised agent cannot rewrite the rules it runs under.
ReadOnlyPaths=/home/claw/pi-workspaces/curator
PrivateTmp=true
UMask=0077
# --- privileges -------------------------------------------------------------
NoNewPrivileges=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectKernelLogs=true
ProtectControlGroups=true
ProtectClock=true
ProtectProc=invisible
RestrictSUIDSGID=true
RestrictRealtime=true
RestrictNamespaces=true
LockPersonality=true
MemoryDenyWriteExecute=false
# node's JIT needs writable-executable pages, so MemoryDenyWriteExecute cannot
# be enabled while pi runs as a child of this service.
# --- resources --------------------------------------------------------------
# pi is a node process and the service may run several sequentially. These are
# ceilings that turn a runaway into a restart instead of host memory pressure.
MemoryMax=3G
MemoryHigh=2G
TasksMax=512
# NOTE: the listener is still on CURATOR_HOST=0.0.0.0, which reaches every
# interface including six docker bridges, and access genuinely arrives from both
# the LAN and 127.0.0.1. The defence is now authentication (plan P2-6): every
# route except /api/health and /login requires CURATOR_WEB_TOKEN, which is what
# makes an unaudited LAN host into a read-only observer instead of a write
# primitive. Do not unset CURATOR_WEB_TOKEN while the port is not loopback.
[Install]
WantedBy=default.target