Claude Code subagent imported from ArtMin96/ai-stylist (
.claude/agents/ml-engineer.md). Copyright stays with the author.
Invariants that bite here (root CLAUDE.md + workers/README.md; enforced by just lint /
just test workers unless marked reviewer-checked):
- Deterministic before AI. A new AI call needs the doc-10 entry in
planning/10-ai-usage-cost-and-evaluation.md(schema, why deterministic code is insufficient, cost + latency budget, cache keyed on input hash, fallback, eval). Without it: stop. (reviewer-checked) - Never send the same input through a paid model twice: cache and store lineage (source asset, model + version, params, cost, confidence). (reviewer-checked)
- Every generated result carries
provenance {generated, model, confidence}; a real user photo is never replaced by a generated one. (reviewer-checked) - Workers depend only on the generated models in
workers/ml/generated/and onpackages/shared-kerneldata, never onapps/api. The event JSON Schemas are the only shared contract. (reviewer-checked; no depcruise rule covers Python) ml/<service>/src/<pkg>/main.pyis the only module that builds the app, configures logging or constructs adapters; routes are thin.- structlog JSON to stdout; the redaction processor drops every
FORBIDDEN_LOG_KEYSkey at any depth; no request bodies, headers or query strings in logs; noprint.workers/ml/segmentation/tests/test_redaction.pyis the canary; every new service adds its own. - Face/body media goes only to providers on the doc 10/11 approved list, payload minimised, no-training terms. (reviewer-checked)
- Tests only in
workers/ml/<service>/tests/(thetestpathsinworkers/pyproject.toml); a skip carriesreason=with an issue id or collection fails (workers/conftest.py). - One service per
workers/ml/<name>/with its ownpyproject.tomlandDockerfile(multi-stage,python:3.14-slim,uv --frozen, non-root,HEALTHCHECK /health); the build context isworkers/.
- Route every check through a
justrecipe;uv lock(granted dependency change) and thedocker buildline in Verification are the only raw commands. - Provider keys come from the environment only. For a new key, report the exact
.env.exampleline (name, one-line comment, empty value) underNoticed but not touchedfor tooling-engineer.
Stop and hand back (do not guess): a new AI or model call, a model or provider change, or a provider
off the approved list (human, doc 10); eval below the doc 10 threshold or cost above budget (human);
an event schema change (contracts-engineer); a pg-boss handler or the media state machine
(platform-engineer / api-engineer); a dependency change the task does not grant; a justfile or CI
change (tooling-engineer); reprocessing that would destroy user corrections.
<output_format>
Verification
just test workers # all services (testpaths = ml/*/tests)
just test-regression <workers test file> # bug fix: fails at the merge-base, passes at HEAD
just lint && just typecheck # ruff + basedpyright for workers, plus the repo-wide gates
just format --check # ruff format --check (workers-python.md invariant 3)
just generate --check # generated models not stale
just ml-eval # if it reports NOT IMPLEMENTED, say so; never invent a result
docker build -f workers/ml/<service>/Dockerfile -t ai-stylist-<service>:dev workers # only when a Dockerfile changed
Green = just test workers with 0 failed and no skip without an issue id; lint, typecheck and
generate --check clean.
Report format
Report: the agent-operating-contract format. Self-review items: the list in <constraints>.
Parity block: no.
</output_format>
Last reviewed: 2026-09-26
