To målinger avgjorde formen FØR koden: (1) hosting-pakkas InvocationsHostServer
finnes kun i bygg som krever agent-framework-core>=1.13.0 (treet låser 1.9.0;
eneste 1.9-kompatible bygg er en forlatt alfa som importerer mcp udeklarert),
(2) et gjenbrukt bygget workflow er single-use på 1.9.0 (kall-serie [2,0,0] —
rundetaket persisterer; ferskt objekt per kall er ren kontroll). Derfor spikens
§5-fallback: hosting.py serverer kontrakten (8088/PORT, /readiness,
/invocations, SIGTERM→0) selv, stdlib asyncio på ÉN løkke — aldri as_agent()
(gatene ligger utenfor grafen), aldri tråder (NG1-guarden fanget første utkast
med ThreadingHTTPServer; asyncio-formen består den by construction).
Payload whitelistes på run_projects signatur — ukjente felt nektes ved navn
(400), aldri stille droppet; profile defaulter til azure kun her. ValueError →
400, alt annet → 500 {error_type, error}; Rejection er vellykket kjøring → 200.
outbox.outcome_payload ekstrahert som den ENE kopien av validated/rejected-
forgreningen (kø-(p)-regelen). azure.yaml validert GRØNN mot begge autoritative
skjemaer (jsonschema, hentet ferskt); ingen env:, ingen startupCommand (imagets
CMD er den ene kopien). Dockerfile: 3.12-slim-bookworm + git + uv==0.9.8 +
uv sync --frozen --no-dev; git archive <indeks-tre> | docker build
--platform linux/amd64 grønn på nøyaktig de stagede bytene.
Iron Law fulgt: testfila rød ved collection FØR modulen fantes. 835 passed /
4 skipped (fra 821), ruff+format+mypy rene. Seks mutasjoner mot HELE suiten,
alle røde på riktig test: detach felt-mappingen · dropp ukjente felt stille ·
flipp 400/500 · detach azure-defaulten · detach SIGTERM-handleren · detach
main.py-shimen (de to siste kun fanget av subprosess-testen, P4-presedensen).
Deploy IKKE utført — azd-steget er operatørens.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PEiiSGRShizKc771ZBa1iq
35 lines
1.7 KiB
Docker
35 lines
1.7 KiB
Docker
# Hosted-agent container (Fase 4d). Build context is `git archive HEAD` — what a stranger
|
||
# actually downloads, never the working tree — and the hosting platform requires x86_64
|
||
# (spike §1.4), so the measured build command is:
|
||
#
|
||
# git archive HEAD | docker build --platform linux/amd64 -t portfolio-optimiser -
|
||
#
|
||
# Base: the version pinned by .python-version (3.12), mid-band of the resolution matrix
|
||
# (3.10–3.13 have numpy wheels, 3.14 does not — spike §4), and the same base Microsoft's
|
||
# own MAF sample uses. Runs as root like that sample: no non-root requirement is
|
||
# documented (spike, Ikke verifisert pkt. 7).
|
||
FROM python:3.12-slim-bookworm
|
||
|
||
# git: the two security components are git-tag-pinned direct references, and
|
||
# [tool.uv.sources] never reaches wheel metadata (spike §3/§7.2) — uv needs the git CLI
|
||
# to fetch them, and -slim ships without it.
|
||
RUN apt-get update \
|
||
&& apt-get install -y --no-install-recommends git \
|
||
&& rm -rf /var/lib/apt/lists/*
|
||
|
||
# Pinned to the uv the tree was measured with (13.08) — an unpinned installer would let
|
||
# the container's resolver drift from the working tree's.
|
||
RUN pip install --no-cache-dir uv==0.9.8
|
||
|
||
WORKDIR /app
|
||
COPY . .
|
||
|
||
# The LOCKED, dev-free environment — the same resolution the working tree was measured
|
||
# with (agent-framework-core 1.9.0). Never a fresh resolve from pyproject.toml: that
|
||
# picks other versions (1.13.0) than every measurement in this repo ran against (§3).
|
||
RUN uv sync --frozen --no-dev
|
||
|
||
# The hosted-agent runtime contract: port 8088, GET /readiness, POST /invocations,
|
||
# SIGTERM shutdown (spike §1.1) — served by main.py (portfolio_optimiser.hosting).
|
||
EXPOSE 8088
|
||
CMD ["/app/.venv/bin/python", "main.py"]
|