Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
5.6 KiB
MP-25 — real FileBot sandbox on server-01 (filebot-cli-sandbox + exec-only socket gateway) (spawned 2026-10-01, main session 771b2744)
You are a bounded background agent for media_pipeline (tracking row personal_projects #61). Budget: --max-turns 50. Same tool call twice with identical arguments → STOP with a partial wrap-up.
GOAL (owner 2026-10-01 18:20): the sandbox filebot-monitor must run against a REAL FileBot, so file-monitor fixes (MP-24 now; FM-2/FM-4 later) are tested end to end. Build everything up to — NOT including — license activation; the main session activates with the owner's license file afterwards. Then resume-ready: once activated, the end-to- end test (section E) runs.
FACTS (main session, verified 18:20):
- Live prod: container filebot-cli = rednoah/filebot:latest (FileBot 25.04, image id
sha256:02fb2211c90ccb40e3cabfba7dfd94b57077aaf1c5f087d3da64c32c9b57c116), on PRIMARY. filebot-monitor execs
docker exec filebot-cli filebot ...via docker.sock. Inspect both live containers READ-ONLY (docker inspect: mounts, env KEY NAMES only, user, entrypoint) to mirror the sandbox faithfully. - server-01 has NO filebot-cli container or image. It has gitea.local/backtalk6858/filebot-monitor:latest.
- Sandbox: /opt/appdata/docker/docker-compose/server-01/media-pipeline-sandbox/ (git twin on primary, live copy on
server-01). Service filebot-monitor-sandbox exists behind compose profile
mp14; it sys.exit(1)s unlessdocker exec filebot-cli filebot -versionworks. Its working copy file-monitor.py = MP-24 build sha 057708dc… (do not modify it; if the container namefilebot-cliis hardcoded, make the sandbox reach the sandbox FileBot WITHOUT editing the code — e.g. name the sandbox FileBot container so the exec target resolves, or an env var the code already reads; report which). - OWNER DECISION 2026-09-23 (MP-12): NO raw docker.sock in the sandbox — server-01 also runs prod (n8n-prod, hermes, jenkins); a socket would let the sandbox exec into those. Today's design (main session, keeps that intent): an EXEC-ONLY socket gateway that can reach ONLY the sandbox FileBot container.
DECISIONS (pre-made):
- D1 FileBot: service
filebot-cli-sandboxin the sandbox compose, image rednoah/filebot pinned by DIGEST to the same version as prod (25.04; resolve the digest of the live image id above — pull that exact digest on server-01; if the exact digest cannot be found on Docker Hub, use the newest 25.04-tagged digest and say so). Same mounts as prod but pointing at sandbox dirs (sandbox-renamed/…, sandbox-library/…, sandbox-filebot-staging). Its FileBot data dir (where the license is stored) on a named volumefilebot-sandbox-dataso activation survives recreates. Long- running (same command/entrypoint pattern as prod sodocker execworks). No ports, sandbox network only. - D2 Gateway: wollomatic/socket-proxy (pin a digest; check its README for the current flags) with an allowlist of
ONLY: GET /_ping, GET /version, GET /containers//json, POST
/containers//exec, POST /exec/[a-f0-9]+/start, GET /exec/[a-f0-9]+/json (+ resize if the docker CLI
needs it). Everything else denied. Mounted docker.sock read-only on the gateway ONLY. filebot-monitor-sandbox gets
DOCKER_HOST=tcp://: (no socket mount). Prove the restriction: from inside filebot-monitor-sandbox,
docker ps→ denied;docker exec n8n-prod-h10eww4au274owpxozgizysh true→ denied;docker exec <sandbox filebot> filebot -version→ works (license-free command). If the filebot-monitor image has no docker CLI, report how it execs (python docker SDK?) and adapt the allowlist accordingly. - D3 Keep everything behind the
mp14profile (plaindocker compose up -dmust not start them).
HARD RULES
- You MAY create/start/stop/recreate ONLY media-pipeline-sandbox-* containers + the two new sandbox services on
server-01 (log "ELEVATED "). NEVER touch prod containers on either host. NO git, NO Postgres writes on primary,
NO sudo (
⏸ OWNER-COMMAND-REQUESTblock if needed). Never read or print the license file or any .env/secret value. - Edit the sandbox compose on BOTH copies (primary twin + server-01) identically; keep a .bak-mp25 of each first.
- STOP before activation: the license is the main session's step.
E. END-TO-END (only after the main session resumes you saying "activated"): stage one fixture through the real FileBot via filebot-monitor-sandbox: (1) happy path → lands in sandbox-library; (2) collision: pre-place a different file at the target name → incoming lands in _conflicts, library untouched; record FileBot's exact stdout/exit code for the skip (verifies MP-24's regex); (3) clean up sandbox dirs. Use real-ish names the downloader won't skip (e.g. 'Yu Yu Hakusho - S01E01.mkv' from the mp6/mp10 fixture library).
PERSIST: append "## MP-25 — 2026-10-01 (background agent)" to
/opt/appdata/docker/docker-compose/media-downloader-local/.claude/context.md; run
python3 /opt/appdata/docker/.claude/scripts/embed_memory_dir.py --only-recent 5.
FINAL message = wrap-up JSON only: status, project "media_pipeline", phase ("built_awaiting_activation" | "e2e_done"),
filebot_image_digest, gateway_image_digest, gateway_allowlist[], restriction_proofs[] (command, result),
exec_target_mechanism, license_activation_command (exact docker exec ... filebot --license /path with the path the
main session should copy the .psm to on server-01), e2e[] (when run), filebot_skip_output (verbatim, when run),
actions_taken[], actions_failed[], containers_elevated[], unverified_claims[], next_step, notes.