# Compile-pod image = Python + both agent SDK adapters + the kbc compile brain.
#
# Each pinned SDK ships its matching runtime binary; /session selects exactly
# one engine for a run (claude_agent_sdk or codex_sdk).
#
# build:  docker build -f platform/pod/Dockerfile -t kbc-compile-pod .   (run from kbc/ = build ctx)
# run (production; LLM via an Anthropic-compatible model proxy):
#   docker run --rm \
#     -e ANTHROPIC_BASE_URL=https://<model-proxy>/   \   # model goes through the proxy; key injected proxy-side
#     -e ANTHROPIC_API_KEY=<token>               \   # or pass a key directly
#     -v /path/to/workdir:/work                  \   # workdir with raw sources
#     kbc-compile-pod
FROM python:3.11-slim

RUN apt-get update && apt-get install -y --no-install-recommends git ca-certificates bubblewrap poppler-utils \
    && rm -rf /var/lib/apt/lists/*

# Pin the SDK: an unpinned install drifts on every rebuild, and the bundled
# Claude Code CLI drifts with it (API request-shape changes can break the
# proxy/Bedrock path). 0.2.110 is production-proven on the KB compile path.
# PyYAML backs deterministic OKF frontmatter validation. python-pptx/openpyxl/
# python-docx let office_ingest pre-render .pptx/.xlsx/.docx sources to markdown
# (PDFs are rendered by the agent's Read tool through poppler-utils; text and
# images are read directly).
COPY platform/pod/requirements.txt /tmp/kbc-requirements.txt
RUN pip install --no-cache-dir -r /tmp/kbc-requirements.txt

WORKDIR /app
# CLAUDE.md is only for the legacy CLI (compile_agent.py walks parents for it).
# Do NOT set KBC_PLAYBOOK here: the served box selects its playbook from the
# locale prompt packs (prompts/<locale>/playbook.md); the env is a local-dev
# escape hatch and setting it in the image would override every locale.
COPY CLAUDE.md /app/CLAUDE.md
# All pod modules via a glob so a new one can never be forgotten again (2026-07-07:
# incremental.py was omitted from the explicit list and crashed the box on startup
# with ModuleNotFoundError). test_*.py are excluded via kbc/.dockerignore.
COPY platform/pod/*.py /app/
COPY platform/pod/prompts/ /app/prompts/
COPY tools/ /app/tools/

# Docker preserves build-context modes for copied files. Normalize the whole
# application tree so a checkout created under a restrictive umask cannot make
# the root-owned sources unreadable after the image switches to USER kbc.
# Keep the tree root-owned and non-writable by the runtime user.
RUN chmod -R u=rwX,go=rX /app

# Tenant isolation: never load external memory (prevents cross-tenant bleed).
ENV CLAUDE_CODE_DISABLE_AUTO_MEMORY=1
# The proxy/Bedrock path rejects the `context_management` request field (HTTP 400).
# Root cause (2026-07-06, see compile_box.py header): the thinking-clear
# context edit rides the experimental context-management beta — DISABLE_
# EXPERIMENTAL_BETAS is the real kill switch; autocompact-off stays as
# belt-and-braces. The Python modules also setdefault these; the ENV makes
# the posture visible at the image level.
ENV CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1 DISABLE_AUTOCOMPACT=1 DISABLE_AUTO_COMPACT=1
# Default served port (overridable via SICLAW_AGENTBOX_PORT, aligned with agentbox).
ENV SICLAW_AGENTBOX_PORT=3000

# Run as non-root (the Agent SDK's bypassPermissions refuses root; also sandbox
# best practice).
RUN useradd -m -u 1000 kbc
USER kbc

EXPOSE 3000

# Served form: spawned by the siclaw runtime, driven over the box's own
# HTTP+SSE contract (POST /session, /message, SSE /events). The one-shot CLI
# form remains in compile_agent.py (local debugging: python compile_agent.py
# --workdir /work).
ENTRYPOINT ["python", "/app/compile_box.py"]
