Run durable process trainers through Docker Compose with the same reservation, receipt and cancellation contract

Merged
UN
5d ago
+669-35

Recursive programmes can now select adapter.kind: "compose-bandit" with a local immutable image ID through the durable process controller. Each generation uses the existing content-bound job, approved resource reservation, staged receipt validation, settlement and promotion checks.

The controller generates a job-scoped, networkless Compose project with only job artifacts mounted, no host ports, a read-only root filesystem, dropped capabilities and the invoking numeric UID/GID. Cleanup resolves the exact named and labelled container and removes its immutable daemon ID. Recovery adopts valid staged completion without retraining or retains incomplete staging with a terminal outcome.

Cleanup errors previously replaced trainer errors in finally, misclassifying cancellation and rejecting successful runs. Launch and recovery now report cleanup: { code: "cleanup_failed", error } separately in the durable job body and transition history. A valid completion stays materialized, cancellation retains process_cancelled, and trainer failure retains its original error. Diagnostic text is bounded to 4,096 characters and replaces the staging directory with <staging>. Cleanup failures can still leave job resources requiring inspection.

Fifteen tests use real Docker Compose and real temporary SDK trackers. The four cleanup regressions run real container launch/training/kill/removal and inject only the compose down failure through the executable boundary; no SDK mocks. They cover cancellation, success, trainer failure and recovery of completed staging. Existing drills cover launch/replay, contention, crash windows, independent tracker isolation, missing receipts and two changed promoted generations.

Behavioural revert proof: restoring only the throwing cleanup in launchComposeTrainer fails all three primary-outcome regressions (0/3 pass); separately restoring the recovery cleanup behavior fails its regression (0/1 pass). Fixed code passes 4/4 through the linked pm test snapshot run. Original Compose feature reverts remain recorded on the PM item.

Validation: npm run release:check and bun run release:check each pass 582/582 tests, zero failures/skips/cancellations/todo, exact 100/100/100/100 statement/line/branch/function coverage across 28 sources, 266 documented declarations, zero duplication and zero production audit findings. Identity, release attestation, packaging and changelog checks pass under isolated CI Git/home settings. All thresholds, dependency pins and CLI deadlines are unchanged. The packed LM CLI measured 12.623 seconds (npm) and 12.272 seconds (Bun), within its unchanged 20-second bound.

PM result tracking is disabled by project policy; tracker comments preserve the gate and revert results. Kernel CPU/storage enforcement and existing packed LM CLI timing variability remain separate follow-ups. Items remain open for orchestrator verification.

PM items:


Summary by cubic

Adds Docker Compose execution for durable process trainers so recursive programmes can select a container trainer through the same controller that runs local process trainers, using the same reservation, receipt, and cancellation contract. Kernel-enforced CPU and storage quotas remain a separate follow-up.

Container execution

  • New adapter.kind: "compose-bandit" runs the trainer as an immutable container image inside a job-scoped, networkless Compose project with only job artifacts mounted, no host ports, a read-only root filesystem, dropped capabilities, and the invoking numeric UID/GID.
  • Cleanup resolves the named and labelled container, removes its immutable daemon ID, and retains stop/cancellation evidence; a cleanup failure no longer masks a valid trainer completion or validated staging.
  • Recovery adopts valid staged completion without retraining or terminates incomplete work with retained staging; cleanup failures now report a separate cleanup: { code: "cleanup_failed", error } diagnostic in the durable job body and transition history.

Tests

  • The suite uses the real Docker Compose CLI with tiny locally built Node fixtures, covering launch, receipt, replay, container death, cancellation, competing controllers, both crash windows, tracker isolation, missing completion, cleanup failure, and two changed promoted generations.
  • Behavioral revert proofs confirm the old parser, reserved execution, recovery guard, and cleanup masking each break expected cases; the implementation passes all tests.

Summary by Sourcery

Run durable process trainers through isolated Docker Compose jobs while preserving the shared resource, receipt, recovery, and outcome semantics.

New Features:

  • Add Docker Compose execution for durable bandit trainers using immutable local images and the existing reservation, receipt, cancellation, recovery, and promotion contract.

Bug Fixes:

  • Preserve trainer outcomes and validated completions when cleanup fails, while recording bounded cleanup diagnostics separately.

Enhancements:

  • Isolate Compose jobs with networkless, least-privilege, job-scoped container configurations and exact container ownership cleanup.
  • Document the Compose adapter, lifecycle, recovery semantics, diagnostics, and validation results.

Build:

  • Include the Compose module and integration tests in the published package and test configuration.

Documentation:

  • Update recursive training and process-trainer documentation to describe Docker Compose support and its remaining kernel quota limitations.

Tests:

  • Add real Docker Compose integration coverage for execution, replay, contention, cancellation, container death, recovery, isolation, staged receipts, successor generations, and cleanup regressions.

Chores:

  • Record PM task and history entries for Compose execution and related follow-ups.