code-sandboxes 1.9.7__tar.gz → 1.9.8__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/CHANGELOG.md +13 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/PKG-INFO +1 -1
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/__version__.py +1 -1
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/environments/attest.py +58 -20
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_environment_attest.py +43 -1
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/.github/workflows/build.yml +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/.github/workflows/environments-live.yml +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/.github/workflows/py-code-style.yml +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/.github/workflows/py-tests.yml +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/.github/workflows/py-typing.yml +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/.github/workflows/reusable-python.yml +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/.gitignore +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/.licenserc.yaml +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/.pre-commit-config.yaml +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/.vscode/settings.json +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/Dockerfile +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/LICENSE +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/Makefile +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/README.md +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/build.log +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/__init__.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/base.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/bridge_mount.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/builds.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/cli.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/client.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/cloudflare_sandbox.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/commands.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/console.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/contents.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/coreweave_sandbox.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/datalayer_sandbox.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/daytona_sandbox.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/docker_sandbox.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/e2b_sandbox.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/environments/__init__.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/environments/__main__.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/environments/accounts.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/environments/adapters/__init__.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/environments/adapters/datalayer.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/environments/adapters/daytona.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/environments/adapters/e2b.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/environments/adapters/managed.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/environments/adapters/modal.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/environments/bases.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/environments/breaker.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/environments/build_secrets.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/environments/builders.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/environments/canonical.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/environments/conformance.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/environments/constraints/sandbox-contract-v1.txt +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/environments/constraints/wheelhouse/README.md +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/environments/constraints/wheelhouse/jupyter_server-2.21.0+datalayer.1-py3-none-any.whl +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/environments/contract.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/environments/doctor/__init__.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/environments/doctor/build.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/environments/doctor/datalayer_sandbox.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/environments/doctor/report.schema.json +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/environments/errors.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/environments/files.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/environments/image_import.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/environments/lifecycle.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/environments/policy.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/environments/redact.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/environments/resolve.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/environments/schema.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/environments/spec.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/eval_sandbox.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/exceptions.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/filesystem.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/google_colab.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/google_colab_sandbox.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/interfaces.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/jupyter_ingress.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/jupyter_server_sandbox.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/kaggle.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/kaggle_execute.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/kaggle_live.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/kaggle_sandbox.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/lifecycle.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/manage.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/modal_sandbox.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/models.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/monty_sandbox.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/provider_ingress.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/providers.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docker/Dockerfile +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/.gitignore +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/LICENSE +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/Makefile +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/README.md +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/babel.config.js +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/docs/api-reference/_category_.yml +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/docs/api-reference/index.mdx +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/docs/cli/_category_.yml +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/docs/cli/index.mdx +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/docs/contribute/_category_.yml +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/docs/contribute/index.mdx +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/docs/environments/_category_.yml +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/docs/environments/contract.mdx +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/docs/environments/index.mdx +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/docs/environments/specification.mdx +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/docs/environments/spike-2026-09.mdx +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/docs/examples/_category_.yml +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/docs/examples/index.mdx +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/docs/guide/_category_.yml +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/docs/guide/index.mdx +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/docs/index.mdx +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/docs/install/_category_.yml +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/docs/install/index.mdx +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/docs/provider-ingress.mdx +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/docs/providers/_category_.yml +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/docs/providers/cloudflare.mdx +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/docs/providers/coreweave.mdx +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/docs/providers/datalayer.mdx +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/docs/providers/daytona.mdx +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/docs/providers/docker.mdx +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/docs/providers/e2b.mdx +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/docs/providers/eval.mdx +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/docs/providers/google-colab.mdx +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/docs/providers/index.mdx +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/docs/providers/jupyter-server.mdx +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/docs/providers/kaggle.mdx +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/docs/providers/modal.mdx +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/docs/providers/monty.mdx +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/docusaurus.config.js +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/package.json +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/sidebars.js +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/src/components/HomepageRow1.js +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/src/components/HomepageRow1.module.css +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/src/components/HomepageRow2.js +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/src/components/HomepageRow2.module.css +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/src/components/HomepageRow3.js +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/src/components/HomepageRow3.module.css +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/src/css/custom.css +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/src/pages/index.module.css +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/src/pages/markdown-page.md +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/src/theme/CustomDocItem.tsx +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/src/theme/IconsTitle.tsx +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/static/img/bricks.svg +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/static/img/building-construction.svg +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/static/img/cloud-sun.svg +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/static/img/cloud.svg +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/static/img/collaboration.svg +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/static/img/copy-left.svg +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/static/img/datalayer/logo.png +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/static/img/datalayer/logo.svg +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/static/img/datalayer/personas/business.svg +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/static/img/datalayer/personas/data-scientist.svg +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/static/img/datalayer/personas/devops.svg +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/static/img/datalayer/project/project-line.svg +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/static/img/favicon.ico +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/static/img/jupyter.svg +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/static/img/open-source.svg +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/static/img/react-js.svg +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/static/img/react-js2.svg +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/static/img/ringed-planet.svg +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/static/img/robot.svg +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/static/img/rocket.svg +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/static/img/shield.svg +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/static/img/sparkles.svg +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/static/img/streamlit.gif +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/static/img/super-hero.svg +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/static/img/target.svg +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/static/img/thumbs-up.svg +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/examples/README.md +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/examples/exec/Makefile +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/examples/exec/cloudflare_sandbox_example.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/examples/exec/coreweave_sandbox_example.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/examples/exec/datalayer_sandbox_example.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/examples/exec/daytona_sandbox_example.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/examples/exec/docker_sandbox_example.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/examples/exec/e2b_sandbox_example.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/examples/exec/eval_sandbox_example.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/examples/exec/google_colab_sandbox_example.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/examples/exec/jupyter_server_sandbox_example.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/examples/exec/kaggle_sandbox_example.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/examples/exec/modal_sandbox_example.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/examples/exec/monty_sandbox_example.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/examples/repl/Makefile +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/examples/repl/cloudflare_sandbox_example.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/examples/repl/coreweave_sandbox_example.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/examples/repl/datalayer_sandbox_example.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/examples/repl/daytona_sandbox_example.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/examples/repl/docker_sandbox_example.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/examples/repl/e2b_sandbox_example.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/examples/repl/eval_sandbox_example.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/examples/repl/google_colab_sandbox_example.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/examples/repl/jupyter_server_sandbox_example.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/examples/repl/kaggle_sandbox_example.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/examples/repl/modal_sandbox_example.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/examples/repl/monty_sandbox_example.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/pyproject.toml +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/schemas/environment-v1alpha1.json +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/__init__.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/conftest.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_a_datalayer_sandbox_can_be_interrupted.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_bridge_mount.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_builds.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_cli_exec.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_cli_repl.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_client.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_client_contents.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_client_files.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_client_outcome_error_output.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_cloudflare.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_commands_envelope.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_console.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_contents_contract.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_contents_live_matrix.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_coreweave.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_datalayer_sandbox.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_daytona.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_e2b.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_environment_accounts.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_environment_bases.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_environment_breaker.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_environment_build_secrets.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_environment_builders.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_environment_canonical.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_environment_conformance.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_environment_constraints.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_environment_contract.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_environment_cross_variant_report.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_environment_datalayer_builder.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_environment_daytona_builder.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_environment_doctor.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_environment_e2b_builder.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_environment_errors.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_environment_image_import.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_environment_lifecycle.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_environment_live_matrix.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_environment_managed_builders.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_environment_modal_builder.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_environment_redact.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_environment_resolve.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_environment_spec.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_eval.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_every_variant_has_a_real_interrupt.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_factory.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_google_colab.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_integration.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_jupyter_ingress.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_jupyter_server.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_jupyter_server_streaming.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_kaggle.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_kaggle_execute.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_kaggle_live.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_kaggle_session.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_kernel_client_compatibility.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_lifecycle_vocabulary.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_manage.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_manage_datalayer.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_modal_google_colab_sandbox.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_modal_session.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_models.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_output_line_fidelity.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_provider_catalog_names.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_provider_ingress.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_providers.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_sandboxes.py +0 -0
- {code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/tests/test_the_kill_relaunch_drill.py +0 -0
|
@@ -8,6 +8,19 @@
|
|
|
8
8
|
|
|
9
9
|
## Unreleased
|
|
10
10
|
|
|
11
|
+
## 1.9.8
|
|
12
|
+
|
|
13
|
+
- **Every page of a scan's findings is read before deciding**
|
|
14
|
+
(`environments.attest`; PLAN_ENV.md E1-08, D-11). `describe_image_scan_
|
|
15
|
+
findings` paginates, and the attestor called it exactly once. Found live
|
|
16
|
+
on r1, 2026-09-14: the first real image with more findings than one page
|
|
17
|
+
had 1,547 enhanced findings, 31 of them critical, and the single-page read
|
|
18
|
+
saw a small enough slice that the decision passed — an image with real,
|
|
19
|
+
unreviewed critical vulnerabilities would have been signed and started. A
|
|
20
|
+
hard cap of 50 pages keeps a pathological registry from paginating
|
|
21
|
+
forever; hitting it logs that more findings went unread rather than
|
|
22
|
+
pretending the scan was complete.
|
|
23
|
+
|
|
11
24
|
## 1.9.7
|
|
12
25
|
|
|
13
26
|
- **cosign signs again under `--use-signing-config=false`** (`environments
|
|
@@ -289,32 +289,70 @@ class Attestor:
|
|
|
289
289
|
detail={"repository": repository, "digest": digest},
|
|
290
290
|
)
|
|
291
291
|
|
|
292
|
+
#: A hard cap on pages read, so a registry that never stops paginating
|
|
293
|
+
#: cannot wedge a build forever — this many pages is already far past any
|
|
294
|
+
#: real image's own finding count (E1-08, found live 2026-09-14: see
|
|
295
|
+
#: `_describe`'s own docstring for why a page limit is not optional).
|
|
296
|
+
_MAX_FINDING_PAGES = 50
|
|
297
|
+
|
|
292
298
|
def _describe(self, *, repository: str, digest: str) -> tuple[str, dict[str, Any]]:
|
|
293
|
-
"""
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
299
|
+
"""Every `DescribeImageScanFindings` page, as one status and one answer.
|
|
300
|
+
|
|
301
|
+
ECR paginates enhanced findings — `nextToken`, not a field this call
|
|
302
|
+
can ask to skip — and a single unpaginated call answers only its first
|
|
303
|
+
page. Found live, 2026-09-14: the first real artifact this pipeline
|
|
304
|
+
scanned had 1,547 enhanced findings across many pages and 31 of them
|
|
305
|
+
critical, and a single-page read passed a decision that should have
|
|
306
|
+
blocked, because none of those 31 were in the one page it happened to
|
|
307
|
+
see. Every page is read and merged before `decide` ever runs.
|
|
308
|
+
"""
|
|
309
|
+
pages = 0
|
|
310
|
+
status = ""
|
|
311
|
+
enhanced: list[Any] = []
|
|
312
|
+
basic: list[Any] = []
|
|
313
|
+
completed_at: Any = None
|
|
314
|
+
token: str | None = None
|
|
315
|
+
while True:
|
|
316
|
+
try:
|
|
317
|
+
kwargs: dict[str, Any] = {
|
|
318
|
+
"repositoryName": repository,
|
|
319
|
+
"imageId": {"imageDigest": digest},
|
|
320
|
+
}
|
|
321
|
+
if token:
|
|
322
|
+
kwargs["nextToken"] = token
|
|
323
|
+
answer = self._client().describe_image_scan_findings(**kwargs)
|
|
324
|
+
except Exception as error:
|
|
325
|
+
if _is_in_progress(error):
|
|
326
|
+
return "IN_PROGRESS", {}
|
|
327
|
+
if _is_missing(error):
|
|
328
|
+
raise EnvironmentsError(
|
|
329
|
+
PROVIDER_ERROR,
|
|
330
|
+
f"The registry has no scan for {digest}: {error}",
|
|
331
|
+
detail={"repository": repository, "digest": digest},
|
|
332
|
+
) from error
|
|
302
333
|
raise EnvironmentsError(
|
|
303
334
|
PROVIDER_ERROR,
|
|
304
|
-
f"The
|
|
335
|
+
f"The scan of {digest} could not be read: {error}",
|
|
305
336
|
detail={"repository": repository, "digest": digest},
|
|
306
337
|
) from error
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
)
|
|
312
|
-
|
|
313
|
-
|
|
338
|
+
status = str(((answer.get("imageScanStatus") or {}).get("status")) or "")
|
|
339
|
+
findings = answer.get("imageScanFindings") or {}
|
|
340
|
+
enhanced.extend(findings.get("enhancedFindings") or [])
|
|
341
|
+
basic.extend(findings.get("findings") or [])
|
|
342
|
+
completed_at = findings.get("imageScanCompletedAt") or completed_at
|
|
343
|
+
pages += 1
|
|
344
|
+
token = answer.get("nextToken")
|
|
345
|
+
if not token or pages >= self._MAX_FINDING_PAGES:
|
|
346
|
+
if token:
|
|
347
|
+
self._log(
|
|
348
|
+
f"Stopped reading {digest}'s scan after {pages} pages, "
|
|
349
|
+
"with more findings still unread"
|
|
350
|
+
)
|
|
351
|
+
break
|
|
314
352
|
return status, {
|
|
315
|
-
"findings": findings,
|
|
316
|
-
"completed_at":
|
|
317
|
-
"scanner": "ECR enhanced" if
|
|
353
|
+
"findings": {"enhancedFindings": enhanced, "findings": basic},
|
|
354
|
+
"completed_at": completed_at,
|
|
355
|
+
"scanner": "ECR enhanced" if enhanced else "ECR basic",
|
|
318
356
|
}
|
|
319
357
|
|
|
320
358
|
@staticmethod
|
|
@@ -90,9 +90,14 @@ class FakeEcr:
|
|
|
90
90
|
enhanced_findings=True,
|
|
91
91
|
signed: set[str] | None = None,
|
|
92
92
|
manifest: dict | None = None,
|
|
93
|
+
pages: list[list[dict]] | None = None,
|
|
93
94
|
) -> None:
|
|
94
95
|
self.statuses = list(statuses)
|
|
95
96
|
self.findings = list(findings)
|
|
97
|
+
#: Each entry is one `describe_image_scan_findings` page's own
|
|
98
|
+
#: findings, read in order and merged by `_describe` — overrides
|
|
99
|
+
#: `findings` when given, to test reading more than one page.
|
|
100
|
+
self.pages = pages
|
|
96
101
|
self.enhanced_findings = enhanced_findings
|
|
97
102
|
self.signed = set(signed or set())
|
|
98
103
|
self.manifest = manifest
|
|
@@ -115,7 +120,7 @@ class FakeEcr:
|
|
|
115
120
|
]
|
|
116
121
|
}
|
|
117
122
|
|
|
118
|
-
def describe_image_scan_findings(self, repositoryName, imageId): # noqa: N803 - boto3's spelling
|
|
123
|
+
def describe_image_scan_findings(self, repositoryName, imageId, nextToken=None): # noqa: N803 - boto3's spelling
|
|
119
124
|
self.asked += 1
|
|
120
125
|
self.scanned.append(imageId["imageDigest"])
|
|
121
126
|
status = self.statuses[min(self.asked, len(self.statuses)) - 1]
|
|
@@ -132,6 +137,18 @@ class FakeEcr:
|
|
|
132
137
|
error.response = {"Error": {"Code": "ImageNotFoundException"}}
|
|
133
138
|
raise error
|
|
134
139
|
key = "enhancedFindings" if self.enhanced_findings else "findings"
|
|
140
|
+
if self.pages is not None:
|
|
141
|
+
index = int(nextToken or "0")
|
|
142
|
+
answer = {
|
|
143
|
+
"imageScanStatus": {"status": status},
|
|
144
|
+
"imageScanFindings": {
|
|
145
|
+
key: list(self.pages[index]),
|
|
146
|
+
"imageScanCompletedAt": "2026-09-12T09:00:00Z",
|
|
147
|
+
},
|
|
148
|
+
}
|
|
149
|
+
if index + 1 < len(self.pages):
|
|
150
|
+
answer["nextToken"] = str(index + 1)
|
|
151
|
+
return answer
|
|
135
152
|
return {
|
|
136
153
|
"imageScanStatus": {"status": status},
|
|
137
154
|
"imageScanFindings": {
|
|
@@ -327,6 +344,31 @@ class TestTheScan:
|
|
|
327
344
|
assert raised.value.code.code == "DL_ENV_PROVIDER_ERROR"
|
|
328
345
|
assert raised.value.detail["digest"] == DIGEST
|
|
329
346
|
|
|
347
|
+
def test_every_page_of_findings_is_read_before_deciding(self) -> None:
|
|
348
|
+
"""Found live, 2026-09-14: a single unpaginated call answered only its
|
|
349
|
+
first page, and a real image with 1,547 findings across many pages
|
|
350
|
+
passed a decision that should have blocked — none of its 31 critical
|
|
351
|
+
findings were on the one page a single call happened to see. Every
|
|
352
|
+
page is now read and merged before `decide` runs."""
|
|
353
|
+
page_1 = [enhanced("CVE-2026-1111", "LOW")]
|
|
354
|
+
page_2 = [enhanced("CVE-2026-1234", "CRITICAL", fixed="2.9.15")]
|
|
355
|
+
page_3 = [enhanced("CVE-2026-2222", "MEDIUM")]
|
|
356
|
+
ecr = FakeEcr(pages=[page_1, page_2, page_3])
|
|
357
|
+
decision = an_attestor(ecr=ecr).scan(repository=REPOSITORY, digest=DIGEST)
|
|
358
|
+
assert decision.decision == "blocked"
|
|
359
|
+
assert [finding.id for finding in decision.blocking] == ["CVE-2026-1234"]
|
|
360
|
+
assert decision.body()["counts"] == {"LOW": 1, "CRITICAL": 1, "MEDIUM": 1}
|
|
361
|
+
assert ecr.asked == 3
|
|
362
|
+
|
|
363
|
+
def test_reading_pages_stops_at_the_cap_rather_than_paginating_forever(self) -> None:
|
|
364
|
+
pages = [
|
|
365
|
+
[enhanced(f"CVE-2026-{n:04d}", "LOW")] for n in range(Attestor._MAX_FINDING_PAGES + 5)
|
|
366
|
+
]
|
|
367
|
+
ecr = FakeEcr(pages=pages)
|
|
368
|
+
decision = an_attestor(ecr=ecr).scan(repository=REPOSITORY, digest=DIGEST)
|
|
369
|
+
assert decision.decision == "pass"
|
|
370
|
+
assert ecr.asked == Attestor._MAX_FINDING_PAGES
|
|
371
|
+
|
|
330
372
|
IMAGE = "sha256:" + "bb" * 32
|
|
331
373
|
ATTESTATION = "sha256:" + "cc" * 32
|
|
332
374
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/environments/adapters/__init__.py
RENAMED
|
File without changes
|
{code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/environments/adapters/datalayer.py
RENAMED
|
File without changes
|
{code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/environments/adapters/daytona.py
RENAMED
|
File without changes
|
|
File without changes
|
{code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/environments/adapters/managed.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/environments/doctor/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/code_sandboxes/environments/doctor/report.schema.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/static/img/datalayer/personas/business.svg
RENAMED
|
File without changes
|
{code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/static/img/datalayer/personas/data-scientist.svg
RENAMED
|
File without changes
|
|
File without changes
|
{code_sandboxes-1.9.7 → code_sandboxes-1.9.8}/docs/static/img/datalayer/project/project-line.svg
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|