Skip to content

refactor(docker): one run_spec builder for every docker run argv - #623

Open
napetrov wants to merge 29 commits into
intel:mainfrom
napetrov:arch/c3b
Open

napetrov wants to merge 29 commits into
intel:mainfrom
napetrov:arch/c3b

Conversation

@napetrov

@napetrov napetrov commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

Summary

docker run argv builders (before)
  repos/container.py      DockerRunner.argv      own flag spelling
  metrics/example_runner  _run_docker            own flag spelling
  harnesses/fidelity.py   run_docker            inline -e / --network host
  harnesses/docker_solver task container        TASK_CONTAINER_HARDENING constant

docker run argv builders (after)
  docker_cmd.run_spec(ContainerPolicy, layout, image, command)
    layout = named flag groups in call order ("init", "hardening", "network", ...)
 docker_solver._start_task_container
-  run_args = ["run", "-d", "--name", c, *TASK_CONTAINER_HARDENING, *net_args, ...]
+  layout = [["-d"], ["--name", c], "init", "cap_drop", "security", "pids", "cap_add", "network", ...]
+  run_spec(task_container_policy(...), layout, image, ["sleep", lifetime])

Evidence

  • Before: tests/fixtures/docker/run_argv_golden.json captured from the base commit.
    After: tests/test_docker_run_argv_differential.py replays the input grid through the public entry points and compares argv byte for byte. Passes on head. One key changed on purpose: sandbox/run_args no longer carries --network (the task policy writes it from sandbox.network), so against main that key fails and every other key matches.
  • scripts/refresh_docker_run_golden.py re-takes the golden; tests/test_refresh_docker_run_golden.py checks a re-take reproduces the committed file byte for byte.
  • Full dokimi suite on head (e86cc3f): 18983 passed, 20 skipped.
  • Edge probe over odd inputs (mem None and negative, cpus None/0.0, unicode workdir, task memory and cpus spellings, fidelity env): base and head output identical.

Merge Danger

Door: two-way (internal refactor; revert restores the old builders)

Argv is intended to be byte-identical. Removed importable names, listed for importers (checked against main, which this branch now contains): dokimi.repos.container.ContainerPolicy, dokimi.docker_cmd.PIDS_LIMIT, dokimi.docker_cmd.TASK_CONTAINER_HARDENING, dokimi.harnesses.container_agent.TASK_CONTAINER_HARDENING, dokimi.harnesses.network_policy.start_args, ContainerPolicy(memory_mb=…). The changelog fragment carries the same list. ContainerSandbox.run_args() no longer returns --network; a caller that runs its output alone gets the default bridge, so it must go through the task policy. cap_add is a new field placed before pids_limit, so positional construction shifts.

Blast Radius: docker run argv of the repo container, example runner, fidelity capture and task container.

Follow-ups

  • Follow-up: drop the per-call-site layouts and let the policy order the flags, once the golden is re-taken with the refresh script (flag order is pinned by the golden today).
  • Changelog: changelog.d/20261112_180000_napetrov_docker-argv-builders.md (Removed) lists the importable names that moved.
  • scripts/refresh_docker_run_golden.py imports the grid from tests/, so it needs the test dependencies (pytest) installed.

🤖 Generated with Claude Code

Each docker run call site spelled its own --network and hardening flags.
Task containers bypassed ContainerPolicy with a module constant.

ContainerPolicy and docker_cmd.run_spec(policy, layout, image, command)
now build the argv for the repo container, the example runner, the
fidelity capture and the solver's task container. A layout names the
flag groups in call order, so every argv keeps its order.

Behaviour is unchanged. tests/test_docker_run_argv_differential.py replays
the grid of inputs through the public entry points and compares the argv
byte for byte with tests/fixtures/docker/run_argv_golden.json, captured
from the base commit.

Out of scope: network_policy.build_args still passes proxy values inline
as --build-arg NAME=value, and sidecar create calls stay inline.

Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
@napetrov
napetrov requested a review from a team as a code owner November 11, 2026 18:35
Copilot AI balanced review requested due to automatic review settings November 11, 2026 18:35
@napetrov napetrov added the skip-changelog No user-visible change: bypasses the changelog fragment check label Nov 11, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

No active review issues were identified for the shared Docker argument-builder refactor.

No open issues 🎉

What changed in this PR

0 new findings; nothing to fix.

This PR centralizes Docker run argument construction in docker_cmd.run_spec, using ContainerPolicy flag groups while preserving each caller’s existing argument order.

Changes:

  • Migrates repository containers, example execution, fidelity capture, and task containers to the shared builder.
  • Adds capability groups and task-container policy defaults; changes network selection to return a network name.
  • Adds golden argument fixtures and differential tests to check byte-for-byte compatibility.
File Description
dokimi/​tests/​test_docker_run_argv_differential.py Adds cross-caller argument comparisons against golden fixtures.
dokimi/​tests/​test_container_policy.py Tests capability flags, resource values, and named groups.
dokimi/​tests/​fixtures/​docker/​run_argv_golden.json Records expected arguments and errors for the input grid.
dokimi/​dokimi/​repos/​container.py Uses the shared builder for repository containers.
dokimi/​dokimi/​metrics/​example_runner.py Uses the shared builder for Docker-backed examples.
dokimi/​dokimi/​harnesses/​network_policy.py Returns the starting network name instead of flags.
dokimi/​dokimi/​harnesses/​fidelity.py Uses shared run and environment argument builders.
dokimi/​dokimi/​harnesses/​docker_solver.py Builds task-container arguments from policy and ordered groups.
dokimi/​dokimi/​harnesses/​container_agent.py Uses policy-generated sandbox network flags.
dokimi/​dokimi/​docker_cmd.py Adds the shared run_spec argument builder.
dokimi/​dokimi/​container_policy.py Adds named flag groups, capabilities, and task-container defaults.

Review effort: Balanced

@exai-bot

exai-bot commented Nov 11, 2026 •

Copy link
Copy Markdown

OpenCodeReview: Commit f57fd1a was not reviewed. This PR has reached its review limit (6 reviews).

CI at `f57fd1a`: 15 still running, 6 passing, 2 skipped
Check Status
Build docs (strict) still running
CLI interface diff still running
CodeQL (actions) still running
CodeQL (python) still running
External catalog smoke test (uxlfoundation/skills) still running
Linux Python 3.11 still running
Linux Python 3.14 still running
Linux Wheels Python 3.11 still running
Linux Wheels Python 3.14 still running
Static checks (ruff, schema, zizmor, licenses, pre-commit, bandit, secrets, changelog, schema com... still running

5 more not listed.

To review this commit: re-request review from exai-bot in the Reviewers list.

<details><summary>Last review (6e42b32): no findings</summary>

Open threads from the bot: 0

</details>

@napetrov napetrov added skip-changelog No user-visible change: bypasses the changelog fragment check and removed skip-changelog No user-visible change: bypasses the changelog fragment check labels Nov 11, 2026
@codecov-commenter

codecov-commenter commented Nov 11, 2026 •

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.72%. Comparing base (f12057b) to head (f57fd1a).
⚠️ Report is 1 commits behind head on main.
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #623   +/-   ##
=======================================
  Coverage   95.71%   95.72%           
=======================================
  Files         415      415           
  Lines       55346    55373   +27     
  Branches     9514     9512    -2     
=======================================
+ Hits        52977    53004   +27     
  Misses       1466     1466           
  Partials      903      903           
Files with missing lines Coverage Δ
dokimi/dokimi/container_policy.py 100.00% <100.00%> (ø)
dokimi/dokimi/docker_cmd.py 100.00% <100.00%> (ø)
dokimi/dokimi/harnesses/container_agent.py 97.87% <100.00%> (ø)
dokimi/dokimi/harnesses/docker_solver.py 97.74% <100.00%> (ø)
dokimi/dokimi/harnesses/fidelity.py 95.72% <100.00%> (-0.04%) ⬇️
dokimi/dokimi/harnesses/network_policy.py 95.73% <100.00%> (ø)
dokimi/dokimi/metrics/example_runner.py 95.97% <100.00%> (ø)
dokimi/dokimi/repos/container.py 91.74% <100.00%> (-0.37%) ⬇️

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@vlad-perevezentsev vlad-perevezentsev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review at 8cc918b. The refactor keeps every docker run argv as it was, and the real launch confirms it. What is left is small: one stale doc name, one argv part the golden does not pin, and some cleanups, all in the line comments.

What I ran, at 8cc918b:

  • make ci-local --offline: 18,397 passed, 0 failed, 72 skipped. The only FAIL is the changelog fragment check, which does not see the skip-changelog label.
  • The differential test and its golden against the merge-base ead342e: it passes, so the golden is the base output.
  • CI's external-catalog-smoke (docker-oracle and docker-probe on onetbb-histogram-local-aggregation): 1/1 pass each, every isolation probe closed. The task container started with the same flags in the same order as before, both on bridge and inside the egress sandbox.
  • A mutation that moves the task container's -e flags after the image: all 515 tests in the docker, container, network-policy and tbench files still pass (see the line comment).

Checked, no issues

  • Call sites: the repo container, the example runner, the fidelity client and the task container build the same flags in the same order as on the base; memory=f"{mem_mb}m" cannot get a None, because _run_docker returns before it when mem_mb is unset.
  • bridged: network == "bridge" gives the same answer as "bridge" in net_args with and without a sandbox; test_network_policy.py fails if it is broken.
  • Removed names: nothing in the tree or on current main still imports TASK_CONTAINER_HARDENING, start_args, docker_cmd.PIDS_LIMIT or memory_mb=; no call builds a ContainerPolicy by position, so the new cap_add field moves nothing.
  • Changelog: no fragment, under skip-changelog; that fits, since no argv changes and the removed names are internal.

Comment thread dokimi/dokimi/container_policy.py Resolved
Comment thread dokimi/dokimi/container_policy.py Resolved
Comment thread dokimi/dokimi/container_policy.py Resolved
Comment thread dokimi/dokimi/docker_cmd.py Resolved
Comment on lines +52 to +56

A layout item is either the name of a :class:`ContainerPolicy` group (``"init"``, ``"hardening"``,
``"network"``, ...), or an argv list already spelled: :func:`mount_args`, :func:`env_args`, or
the caller's own flags (``["--rm"]``, ``["--entrypoint", ""]``). A bare string is always a group
name, so a flag is never written bare. Each caller lists its groups in the order its argv has

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Question: once this lands, does each call site still need its own flag order?

Docker does not care about the order of options before the image. The layouts, the group names and the split of hardening into security / cap_drop exist only to keep four old orders byte-identical. With one fixed group order in run_spec (then the caller's own flags), a later change could drop the layouts, at the cost of one golden refresh.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keeping the per-call-site layouts in this PR: the golden pins each argv's flag order, and dropping the order changes every key. With the refresh script that is cheap as a follow-up, which I will open once this lands.

Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>

# Conflicts:
#	dokimi/dokimi/repos/container.py
coding-harnesses.md named TASK_CONTAINER_HARDENING in docker_cmd.py, which this refactor removed. The test checks the prose for the removed name, since the code-ref check only reads code spans.

Thread: PRRT_kwDOVBg7g862m5Jm
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
The sidecar still spells --network inline, and the module holds the task container's defaults, so the docstring says both. Docstring only.

Thread: PRRT_kwDOVBg7g862m5J0
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
run_spec took any str as a group name and raised KeyError only on the path that ran it. ContainerPolicy.group now takes the Group Literal, run_spec's layout is Iterable[Group | list[str]], and the call sites that build a layout annotate it, so mypy checks every name.

Thread: PRRT_kwDOVBg7g862m5KG
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
…licy

The repo container's four hardening fields were spelled twice: in DockerRunner.argv and in task_container_policy. repo_container_policy(network) now holds them; task_container_policy is that policy plus the task's capabilities, cpus and memory, and DockerRunner.argv uses repo_container_policy. Argv unchanged.

Thread: PRRT_kwDOVBg7g862m5J9
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
…work

The solver passed the policy network=None and the sandbox's run_args added --network, so the policy did not hold the container's real network. The policy now takes sandbox.network; run_args returns the label and tmpfs only. The task/sandboxed argv is unchanged; the sandbox/run_args golden entry loses the --network pair it no longer returns.

Thread: PRRT_kwDOVBg7g862m5Ju
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
The golden had no refresh path, so a planned argv change meant editing a 3,000-line JSON by hand. scripts/refresh_docker_run_golden.py replays the differential grid and writes the golden; a refactor leaves the file byte-identical. The test checks that a re-take reproduces the committed file.

Thread: PRRT_kwDOVBg7g862m5Js
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
No grid case had container_env, so moving the -e flags after the image kept every test green while the container exited at once. The grid adds a terminal-bench task (its TEST_DIR and GREETING come from compose), a test asserts every argv that carries TEST_DIR puts it before the image, and the golden is re-taken with scripts/refresh_docker_run_golden.py: 38 added lines, none changed.

Thread: PRRT_kwDOVBg7g862m5Je
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
The task policy spells --network from sandbox.network, so the sandbox's
run_args no longer carries it, and the layout takes the network once.
Folds the split test back to the main line count and drops two blank
lines in _start_container so both files sit at the growth baseline.

Thread: PRRT_kwDOVBg7g862m5Ju
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
…den script

The Removed fragment lists the docker builder names that moved, since the
package's importable names changed. deptry flags the refresh script's import
of the grid in tests/, so the ignore lists that module, as audit_mocks is.

Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
@napetrov

Copy link
Copy Markdown
Contributor Author

Round 5 is pushed at a357159 (8cc918b..a357159).

  • Review XiBWSA (stale doc name): fixed in f088901.
  • Question KL: the per-call-site layouts stay in this PR, since the golden pins flag order; dropping them is a follow-up, cheap now that the golden is re-taken by a script.
  • PR body corrected: removed-names list against main, the one golden key that changed on purpose, changelog fragment added.

Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>

@vchamarthi vchamarthi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review at e5379c3. 2 new findings: 1 must-fix, 1 nit. In the line comments. The change moves every docker run argv the package builds onto one run_spec builder over ContainerPolicy, and the argv stays byte-identical in the tested grid. The changelog fragment's list of removed importable names omits five names this PR removes or renames.

Verified

  • Argv byte identity: On e5379c3 the argv for every tested input, including repo, example and fidelity, is byte-for-byte identical to main's, and the golden refresh script's output matches the committed golden.
  • Task env pinning: The -e flags of the task start in dokimi/dokimi/harnesses/docker_solver.py put TEST_DIR=/tests before the image.
  • Network: run_args() no longer adds --network. The task start in dokimi/dokimi/harnesses/docker_solver.py takes the network from the task policy instead.
  • Mount path comma: A , in a mount host path makes DockerRunner.argv raise ContainerError before it returns any argv, on 3b61dd0 and on e5379c3 alike.
  • Static checks: On e5379c3 merged onto current main 38d07f9, ruff, the schema check, mypy, deptry, the comment-block check, schema compatibility, the mkdocs build, the CLI snapshot and the fidelity golden all pass. The typed Group literal is part of the passing mypy run.
  • Merge onto main: e5379c3 merges onto current main 38d07f9 with no conflict.

The grid masked every ':/work:ro' argument to <tmp>, so a broken mount source
(/missing:/work:ro) produced the committed golden. The mask now applies only to
a source that holds the snippet, checked while the temp dir still exists.

Thread: PRRT_kwDOVBg7g862yBwq
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
The golden holds POSIX paths; on Windows the grid's Path('/h/run') serialises
with backslashes, so the byte-identity test fails there and a refresh would
write platform-specific arguments into the shared golden. The refresh script
exits 2 on Windows, and the byte-identity test is skipped there.

Thread: PRRT_kwDOVBg7g862y5dE
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
The refresh script exits 2 on Windows, so this test would fail there rather than skip.
Found by the self-review of e4793aa; probe: IS_WINDOWS=True makes main() return 2.

Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
The stale doc name was fixed in f088901, and the task container's -e flags
are pinned before the image by 4ce67d1. Nothing else changes in this commit.

Thread: PRR_kwDOVBg7g88AAAABXiBWSA
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
@napetrov

Copy link
Copy Markdown
Contributor Author

Re: review by vlad-perevezentsev

one stale doc name, one argv part the golden does not pin
a: f088901. b: 4ce67d1.

…pr623-r5

Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
…ngelog

Thread: PRRT_kwDOVBg7g8627Mje
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
…hangelog

Thread: PRRT_kwDOVBg7g8627Mjh
Thread: PRR_kwDOVBg7g88AAAABXsbQsg
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
@napetrov

Copy link
Copy Markdown
Contributor Author

Re: review by vchamarthi

The changelog's list of removed importable names omits five names, and two listed names were never exported
Fixed in bc35c8b: the five names are added and the two are dropped.

…ippet

Signed-off-by: Vladislav Perevezentsev <vladislav.perevezentsev@intel.com>

@vlad-perevezentsev vlad-perevezentsev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

I checked 6e42b32. Every point from my first round is fixed, and the argv each call site builds is still byte-identical to main. Keeping the per-call-site layouts for a follow-up is fine with me.

Merge: safe now: it merges cleanly into current main, 10 commits behind, and its docker, container, network-policy, tbench and docs-refs tests pass on the merge (351 passed). Once it is in, #695 conflicts with it in the import block of docker_solver.py and needs a rebase.

What I ran, at 6e42b32:

  • make ci-local --offline: 18,946 passed, 0 failed, 72 skipped; every check passes.
  • The first round's mutation (the task container's -e flags moved after the image) fails the golden test, the new -e position test and the refresh re-take test.
  • The golden against the merge-base cb6cead: only sandbox/run_args differs, the one key changed on purpose.
  • CI's external-catalog-smoke (docker-oracle and docker-probe), at bc35c8b: 1/1 pass each, every isolation probe closed; the sandboxed task container starts with the same flags as before.
  • On Windows (Server 2025, Python 3.13): not run. The VM venv cannot be built from the base's requirements.lock.txt (filelock==4.2.4 with litellm==1.106.4, which needs filelock<4); this PR does not touch the lock.

Checked, no issues

Fixed in this branch, up to 6e42b32:

  • The example's /work mount was masked whenever a file with the snippet's name was there, so a mount of another directory with a different snippet still matched the golden (the open exai-bot thread): 6e42b32 masks it only when the file holds this run's code, and a new test redirects the mount to such a directory.
    The new test fails with the old is_file() check.

napetrov and others added 3 commits November 13, 2026 13:26
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
Thread: PRRT_kwDOVBg7g863BiVp: already fixed in 6e42b32
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
The Removed bullet names docker_solver.start_args and TASK_CONTAINER_HARDENING, and says the replacement returns a ContainerPolicy rather than a flag list.

Signed-off-by: vchamarthi <123653452+vchamarthi@users.noreply.github.com>
@vchamarthi

Copy link
Copy Markdown
Contributor

Pushed 1 commit to arch/c3b (426a610..0b5ba9a).

  • The Removed bullet names docker_solver.start_args and docker_solver.TASK_CONTAINER_HARDENING with their replacements.
  • The bullet says task_container_policy(network=, cpus=, memory=) returns a ContainerPolicy, not a flag list.
    Run: the full suite with main merged in, 19806 passed.
    Static checks fails on main as well: the committed docs/reference/cli-interface.json is over the 500 KB limit of the pre-commit large-file hook. fix(cli): the CLI snapshot writes one line per parameter #737 fixes it.

@xaleryb

xaleryb commented Nov 14, 2026

Copy link
Copy Markdown
Contributor
  • Ran: the full suite, ruff, mypy, bandit, check_growth and the benchmark docs gate on 0b5ba9a (Python 3.13). All pass except Static checks.
  • tests/test_changelog_docker_argv_fragment.py has no SPDX header -> the License header step fails (the open thread on line 1) -> expected: the two-line header.
  • The same file reads changelog.d/20261112_180000_napetrov_docker-argv-builders.md by name -> with the fragment removed, as scriv collect does at release (scripts/check_release.py refuses while any fragment remains), both tests fail with FileNotFoundError -> expected: no test depends on a fragment that the release deletes.
  • Suggested fix: drop that test file; it only checks the wording of a changelog bullet, and that settles both points.
  • The other Static checks failure (check-added-large-files on docs/reference/cli-interface.json) fails on main too and is not caused by this PR.
  • Earlier review points: all fixed or answered; the per-call-site layout question is deferred to a follow-up, as agreed.

@antonwolfy antonwolfy left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review at 0b5ba9a. The refactor holds: every docker run argv the package builds is the same as on the base, and the new tests pin the security flags. The merge waits for the red Static checks job on GitHub, which comes from the new test_changelog_docker_argv_fragment.py.

What I ran, on a Linux review host at 0b5ba9a:

  • make ci-local with docker: 33 passed, 4 failed. 19,767 tests passed; changed-line coverage, mypy, deptry, ruff, bandit, the fidelity golden and the docker-oracle/docker-probe smoke pass. The failures are not the PR's: pre-commit fails check-added-large-files on docs/reference/cli-interface.json, which this PR does not touch and which is over the limit on main too; the two gitleaks steps failed on a download; two tests in test_audit_test_quality.py hit the 60 s timeout under load and pass alone (172 passed). The PR carries the skip-changelog label.
  • 60 mutants of the new code (layout groups swapped or dropped, cap list, pids limit, --init, --read-only, bridged, network): 59 are killed by the differential, policy, characterization, network-policy and container-agent tests. The survivor swaps the sandbox's --label/--tmpfs flags and the task -e flags, which only changes flag order and has no effect on behaviour.
  • Base against head: the differential test and golden fail against the base only on sandbox/run_args, the one key changed on purpose.

Checked, no issues

  • Call sites: the repo container, example runner, fidelity client and task container build the same flags in the same order as on the base, with and without a sandbox, and bridged=network == "bridge" matches the old "bridge" in net_args.
  • Removed names: no reference to TASK_CONTAINER_HARDENING, start_args, docker_cmd.PIDS_LIMIT or ContainerPolicy(memory_mb=...) is left in the package, docs, scripts or tests.
  • Commits: all 19 non-merge commits carry a Signed-off-by.

I agree with @xaleryb's points on the missing license header in test_changelog_docker_argv_fragment.py and on its dependence on the changelog fragment. New evidence: with the fragment removed from a copy of the tree, both tests fail with FileNotFoundError.

Bot points I checked that no longer apply at this head (1)
  • exai-bot's point on masking the example's /work mount does not apply: the mount is masked only when the snippet file holds this run's code, and a test redirects the mount to a directory with a different snippet.

Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
It read the changelog fragment by name, which scriv removes at release, and it had no SPDX header. The fragment is checked by review.

Thread: PRRT_kwDOVBg7g863XTgj
Thread: IC_kwDOVBg7g88AAAABmY9rIg
Thread: PRR_kwDOVBg7g88AAAABX-4YfQ
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
The merge of main left a noqa that ruff flags once the re-export is gone.

Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
@napetrov

Copy link
Copy Markdown
Contributor Author

Re: comment by xaleryb

Drop the test file
Dropped in 9334a4b. Large-file check passes now.

@napetrov

Copy link
Copy Markdown
Contributor Author

Re: review by antonwolfy

The merge waits for red Static checks
Fixed in 9334a4b: test file dropped, main merged.

@napetrov

Copy link
Copy Markdown
Contributor Author

Re: comment by vchamarthi

Static checks fails on main too
Already fixed: main's snapshot is 301 KB, merged in 8f86847.

@antonwolfy antonwolfy left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. The refactor holds: every docker run argv the package builds is the same as at the base, the security flags are pinned by the tests, and the commits since my last review only drop the changelog-wording test, merge main and remove two unused noqa markers. One nit inline.

What I ran, on a Linux review host at 7b0a3e9:

  • make ci-local with docker: 37 passed, 1 failed, 14 skipped. 20,447 tests passed; changed-line coverage, mypy, deptry, ruff, bandit, pre-commit, the fidelity golden, the changelog-fragment check and the docker-oracle/docker-probe smoke pass. The one FAIL is test_a_fixed_finding_leaves_the_baseline_too in test_audit_test_quality.py, which hit the 60 s timeout under load; the file does not touch this PR, and run alone it passes (172 passed).
  • 44 mutants of the new code (security flags, cap list, pids limit, network, bridged, read-only, layout groups, mount flags): 40 killed by the differential and policy tests. The 4 survivors are a no-op mutant, and three lines this PR did not change (failed_to_start's not timed_out, the value of INFRA_EXIT, the comma check on the container path in mount_args).
  • The golden re-take script run against the base package: the output differs from the committed golden only in the --network pair under sandbox/run_args, the one key changed on purpose.

Checked, no issues

  • Changelog names: every name the fragment lists was importable at the base and is not at head; a grep of docs/, scripts/ and tests/ finds no stale reference.
  • Layouts: the task container's layout (init cap_drop security pids cap_add network sandbox_flags env resource) matches the base order, and bridged=network == "bridge" matches the old "bridge" in net_args.
  • Commits: all 22 non-merge commits carry a Signed-off-by.
  • Repo rules: new Python files carry the SPDX header, docker_solver.py and test_container_agent.py sit at their growth baseline, and the deptry entry is needed because scripts/ imports a test module.

Signed-off-by: Anton Volkov <antonwolfy@gmail.com>

@antonwolfy antonwolfy left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. I pushed a commit per nit, up to f57fd1a, which fix the nit from my review:

  • f57fd1a: dokimi/changelog.d/20261112_180000_napetrov_docker-argv-builders.md:3: the bullet now says ContainerPolicy gains cap_add before pids_limit, so construct it by keyword, and memory is a string such as "512m".

make ci-local at f57fd1a: 0 failed, 38 passed, 14 skipped.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

skip-changelog No user-visible change: bypasses the changelog fragment check

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants