code-sandboxes 1.9.9__tar.gz → 1.9.11__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.
Files changed (262) hide show
  1. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/CHANGELOG.md +30 -0
  2. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/PKG-INFO +1 -1
  3. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/__version__.py +1 -1
  4. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/environments/attest.py +33 -23
  5. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_environment_attest.py +51 -23
  6. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/.github/workflows/build.yml +0 -0
  7. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/.github/workflows/environments-live.yml +0 -0
  8. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/.github/workflows/py-code-style.yml +0 -0
  9. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/.github/workflows/py-tests.yml +0 -0
  10. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/.github/workflows/py-typing.yml +0 -0
  11. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/.github/workflows/reusable-python.yml +0 -0
  12. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/.gitignore +0 -0
  13. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/.licenserc.yaml +0 -0
  14. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/.pre-commit-config.yaml +0 -0
  15. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/.vscode/settings.json +0 -0
  16. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/Dockerfile +0 -0
  17. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/LICENSE +0 -0
  18. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/Makefile +0 -0
  19. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/README.md +0 -0
  20. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/build.log +0 -0
  21. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/__init__.py +0 -0
  22. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/base.py +0 -0
  23. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/bridge_mount.py +0 -0
  24. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/builds.py +0 -0
  25. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/cli.py +0 -0
  26. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/client.py +0 -0
  27. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/cloudflare_sandbox.py +0 -0
  28. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/commands.py +0 -0
  29. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/console.py +0 -0
  30. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/contents.py +0 -0
  31. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/coreweave_sandbox.py +0 -0
  32. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/datalayer_sandbox.py +0 -0
  33. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/daytona_sandbox.py +0 -0
  34. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/docker_sandbox.py +0 -0
  35. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/e2b_sandbox.py +0 -0
  36. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/environments/__init__.py +0 -0
  37. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/environments/__main__.py +0 -0
  38. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/environments/accounts.py +0 -0
  39. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/environments/adapters/__init__.py +0 -0
  40. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/environments/adapters/datalayer.py +0 -0
  41. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/environments/adapters/daytona.py +0 -0
  42. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/environments/adapters/e2b.py +0 -0
  43. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/environments/adapters/managed.py +0 -0
  44. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/environments/adapters/modal.py +0 -0
  45. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/environments/bases.py +0 -0
  46. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/environments/breaker.py +0 -0
  47. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/environments/build_secrets.py +0 -0
  48. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/environments/builders.py +0 -0
  49. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/environments/canonical.py +0 -0
  50. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/environments/conformance.py +0 -0
  51. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/environments/constraints/sandbox-contract-v1.txt +0 -0
  52. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/environments/constraints/wheelhouse/README.md +0 -0
  53. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/environments/constraints/wheelhouse/jupyter_server-2.21.0+datalayer.1-py3-none-any.whl +0 -0
  54. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/environments/contract.py +0 -0
  55. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/environments/doctor/__init__.py +0 -0
  56. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/environments/doctor/build.py +0 -0
  57. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/environments/doctor/datalayer_sandbox.py +0 -0
  58. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/environments/doctor/report.schema.json +0 -0
  59. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/environments/errors.py +0 -0
  60. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/environments/files.py +0 -0
  61. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/environments/image_import.py +0 -0
  62. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/environments/lifecycle.py +0 -0
  63. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/environments/policy.py +0 -0
  64. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/environments/redact.py +0 -0
  65. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/environments/resolve.py +0 -0
  66. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/environments/schema.py +0 -0
  67. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/environments/spec.py +0 -0
  68. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/eval_sandbox.py +0 -0
  69. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/exceptions.py +0 -0
  70. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/filesystem.py +0 -0
  71. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/google_colab.py +0 -0
  72. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/google_colab_sandbox.py +0 -0
  73. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/interfaces.py +0 -0
  74. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/jupyter_ingress.py +0 -0
  75. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/jupyter_server_sandbox.py +0 -0
  76. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/kaggle.py +0 -0
  77. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/kaggle_execute.py +0 -0
  78. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/kaggle_live.py +0 -0
  79. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/kaggle_sandbox.py +0 -0
  80. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/lifecycle.py +0 -0
  81. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/manage.py +0 -0
  82. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/modal_sandbox.py +0 -0
  83. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/models.py +0 -0
  84. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/monty_sandbox.py +0 -0
  85. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/provider_ingress.py +0 -0
  86. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/code_sandboxes/providers.py +0 -0
  87. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docker/Dockerfile +0 -0
  88. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/.gitignore +0 -0
  89. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/LICENSE +0 -0
  90. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/Makefile +0 -0
  91. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/README.md +0 -0
  92. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/babel.config.js +0 -0
  93. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/docs/api-reference/_category_.yml +0 -0
  94. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/docs/api-reference/index.mdx +0 -0
  95. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/docs/cli/_category_.yml +0 -0
  96. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/docs/cli/index.mdx +0 -0
  97. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/docs/contribute/_category_.yml +0 -0
  98. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/docs/contribute/index.mdx +0 -0
  99. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/docs/environments/_category_.yml +0 -0
  100. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/docs/environments/contract.mdx +0 -0
  101. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/docs/environments/index.mdx +0 -0
  102. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/docs/environments/specification.mdx +0 -0
  103. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/docs/environments/spike-2026-09.mdx +0 -0
  104. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/docs/examples/_category_.yml +0 -0
  105. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/docs/examples/index.mdx +0 -0
  106. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/docs/guide/_category_.yml +0 -0
  107. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/docs/guide/index.mdx +0 -0
  108. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/docs/index.mdx +0 -0
  109. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/docs/install/_category_.yml +0 -0
  110. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/docs/install/index.mdx +0 -0
  111. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/docs/provider-ingress.mdx +0 -0
  112. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/docs/providers/_category_.yml +0 -0
  113. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/docs/providers/cloudflare.mdx +0 -0
  114. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/docs/providers/coreweave.mdx +0 -0
  115. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/docs/providers/datalayer.mdx +0 -0
  116. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/docs/providers/daytona.mdx +0 -0
  117. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/docs/providers/docker.mdx +0 -0
  118. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/docs/providers/e2b.mdx +0 -0
  119. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/docs/providers/eval.mdx +0 -0
  120. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/docs/providers/google-colab.mdx +0 -0
  121. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/docs/providers/index.mdx +0 -0
  122. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/docs/providers/jupyter-server.mdx +0 -0
  123. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/docs/providers/kaggle.mdx +0 -0
  124. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/docs/providers/modal.mdx +0 -0
  125. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/docs/providers/monty.mdx +0 -0
  126. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/docusaurus.config.js +0 -0
  127. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/package.json +0 -0
  128. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/sidebars.js +0 -0
  129. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/src/components/HomepageRow1.js +0 -0
  130. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/src/components/HomepageRow1.module.css +0 -0
  131. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/src/components/HomepageRow2.js +0 -0
  132. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/src/components/HomepageRow2.module.css +0 -0
  133. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/src/components/HomepageRow3.js +0 -0
  134. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/src/components/HomepageRow3.module.css +0 -0
  135. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/src/css/custom.css +0 -0
  136. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/src/pages/index.module.css +0 -0
  137. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/src/pages/markdown-page.md +0 -0
  138. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/src/theme/CustomDocItem.tsx +0 -0
  139. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/src/theme/IconsTitle.tsx +0 -0
  140. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/static/img/bricks.svg +0 -0
  141. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/static/img/building-construction.svg +0 -0
  142. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/static/img/cloud-sun.svg +0 -0
  143. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/static/img/cloud.svg +0 -0
  144. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/static/img/collaboration.svg +0 -0
  145. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/static/img/copy-left.svg +0 -0
  146. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/static/img/datalayer/logo.png +0 -0
  147. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/static/img/datalayer/logo.svg +0 -0
  148. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/static/img/datalayer/personas/business.svg +0 -0
  149. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/static/img/datalayer/personas/data-scientist.svg +0 -0
  150. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/static/img/datalayer/personas/devops.svg +0 -0
  151. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/static/img/datalayer/project/project-line.svg +0 -0
  152. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/static/img/favicon.ico +0 -0
  153. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/static/img/jupyter.svg +0 -0
  154. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/static/img/open-source.svg +0 -0
  155. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/static/img/react-js.svg +0 -0
  156. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/static/img/react-js2.svg +0 -0
  157. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/static/img/ringed-planet.svg +0 -0
  158. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/static/img/robot.svg +0 -0
  159. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/static/img/rocket.svg +0 -0
  160. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/static/img/shield.svg +0 -0
  161. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/static/img/sparkles.svg +0 -0
  162. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/static/img/streamlit.gif +0 -0
  163. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/static/img/super-hero.svg +0 -0
  164. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/static/img/target.svg +0 -0
  165. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/docs/static/img/thumbs-up.svg +0 -0
  166. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/examples/README.md +0 -0
  167. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/examples/exec/Makefile +0 -0
  168. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/examples/exec/cloudflare_sandbox_example.py +0 -0
  169. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/examples/exec/coreweave_sandbox_example.py +0 -0
  170. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/examples/exec/datalayer_sandbox_example.py +0 -0
  171. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/examples/exec/daytona_sandbox_example.py +0 -0
  172. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/examples/exec/docker_sandbox_example.py +0 -0
  173. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/examples/exec/e2b_sandbox_example.py +0 -0
  174. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/examples/exec/eval_sandbox_example.py +0 -0
  175. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/examples/exec/google_colab_sandbox_example.py +0 -0
  176. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/examples/exec/jupyter_server_sandbox_example.py +0 -0
  177. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/examples/exec/kaggle_sandbox_example.py +0 -0
  178. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/examples/exec/modal_sandbox_example.py +0 -0
  179. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/examples/exec/monty_sandbox_example.py +0 -0
  180. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/examples/repl/Makefile +0 -0
  181. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/examples/repl/cloudflare_sandbox_example.py +0 -0
  182. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/examples/repl/coreweave_sandbox_example.py +0 -0
  183. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/examples/repl/datalayer_sandbox_example.py +0 -0
  184. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/examples/repl/daytona_sandbox_example.py +0 -0
  185. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/examples/repl/docker_sandbox_example.py +0 -0
  186. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/examples/repl/e2b_sandbox_example.py +0 -0
  187. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/examples/repl/eval_sandbox_example.py +0 -0
  188. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/examples/repl/google_colab_sandbox_example.py +0 -0
  189. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/examples/repl/jupyter_server_sandbox_example.py +0 -0
  190. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/examples/repl/kaggle_sandbox_example.py +0 -0
  191. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/examples/repl/modal_sandbox_example.py +0 -0
  192. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/examples/repl/monty_sandbox_example.py +0 -0
  193. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/pyproject.toml +0 -0
  194. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/schemas/environment-v1alpha1.json +0 -0
  195. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/__init__.py +0 -0
  196. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/conftest.py +0 -0
  197. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_a_datalayer_sandbox_can_be_interrupted.py +0 -0
  198. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_bridge_mount.py +0 -0
  199. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_builds.py +0 -0
  200. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_cli_exec.py +0 -0
  201. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_cli_repl.py +0 -0
  202. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_client.py +0 -0
  203. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_client_contents.py +0 -0
  204. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_client_files.py +0 -0
  205. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_client_outcome_error_output.py +0 -0
  206. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_cloudflare.py +0 -0
  207. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_commands_envelope.py +0 -0
  208. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_console.py +0 -0
  209. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_contents_contract.py +0 -0
  210. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_contents_live_matrix.py +0 -0
  211. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_coreweave.py +0 -0
  212. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_datalayer_sandbox.py +0 -0
  213. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_daytona.py +0 -0
  214. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_e2b.py +0 -0
  215. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_environment_accounts.py +0 -0
  216. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_environment_bases.py +0 -0
  217. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_environment_breaker.py +0 -0
  218. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_environment_build_secrets.py +0 -0
  219. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_environment_builders.py +0 -0
  220. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_environment_canonical.py +0 -0
  221. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_environment_conformance.py +0 -0
  222. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_environment_constraints.py +0 -0
  223. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_environment_contract.py +0 -0
  224. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_environment_cross_variant_report.py +0 -0
  225. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_environment_datalayer_builder.py +0 -0
  226. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_environment_daytona_builder.py +0 -0
  227. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_environment_doctor.py +0 -0
  228. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_environment_e2b_builder.py +0 -0
  229. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_environment_errors.py +0 -0
  230. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_environment_image_import.py +0 -0
  231. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_environment_lifecycle.py +0 -0
  232. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_environment_live_matrix.py +0 -0
  233. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_environment_managed_builders.py +0 -0
  234. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_environment_modal_builder.py +0 -0
  235. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_environment_redact.py +0 -0
  236. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_environment_resolve.py +0 -0
  237. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_environment_spec.py +0 -0
  238. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_eval.py +0 -0
  239. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_every_variant_has_a_real_interrupt.py +0 -0
  240. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_factory.py +0 -0
  241. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_google_colab.py +0 -0
  242. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_integration.py +0 -0
  243. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_jupyter_ingress.py +0 -0
  244. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_jupyter_server.py +0 -0
  245. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_jupyter_server_streaming.py +0 -0
  246. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_kaggle.py +0 -0
  247. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_kaggle_execute.py +0 -0
  248. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_kaggle_live.py +0 -0
  249. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_kaggle_session.py +0 -0
  250. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_kernel_client_compatibility.py +0 -0
  251. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_lifecycle_vocabulary.py +0 -0
  252. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_manage.py +0 -0
  253. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_manage_datalayer.py +0 -0
  254. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_modal_google_colab_sandbox.py +0 -0
  255. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_modal_session.py +0 -0
  256. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_models.py +0 -0
  257. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_output_line_fidelity.py +0 -0
  258. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_provider_catalog_names.py +0 -0
  259. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_provider_ingress.py +0 -0
  260. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_providers.py +0 -0
  261. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_sandboxes.py +0 -0
  262. {code_sandboxes-1.9.9 → code_sandboxes-1.9.11}/tests/test_the_kill_relaunch_drill.py +0 -0
@@ -8,6 +8,36 @@
8
8
 
9
9
  ## Unreleased
10
10
 
11
+ ## 1.9.11
12
+
13
+ - **1.9.10's own fix did not work: `--registry-referrers-mode` only ever
14
+ governs *reading* referrers, never where `sign` writes one** —
15
+ `sign --help` says so outright ("mode for fetching references"), and a
16
+ second live sign on r1, 2026-09-14, confirmed it: the signature still
17
+ landed as an OCI 1.1 referrer, no legacy tag. `Attestor` no longer tries
18
+ to force cosign's own storage choice. Its replay check and its own
19
+ `signature_ref` now ask cosign directly, the same way the Operator's own
20
+ verify will: `can_verify(reference)` runs `cosign verify --key <key>
21
+ --insecure-ignore-tlog=true <reference>` and answers its exit code, and
22
+ `signature_ref` is the digest reference itself — what `cosign verify`
23
+ takes, not a tag it may or may not have written. Signing the same digest
24
+ twice no longer errors the way a second push under the old immutable tag
25
+ once would have, but `can_verify` still avoids it, since two valid
26
+ signatures claiming to be Datalayer's own word on one artifact is not
27
+ the design either.
28
+
29
+ ## 1.9.10
30
+
31
+ - **cosign signs the legacy tag again, not just an OCI referrer**
32
+ (`environments.attest`; PLAN_ENV.md E1-09). cosign 3.1.3 defaults to the
33
+ OCI 1.1 referrers API for a signature's own storage, not the classic
34
+ `sha256-<hex>.sig` sidecar tag. Found live on r1, 2026-09-14: `cosign
35
+ sign` reported success — the first artifact this pipeline ever actually
36
+ signed — but pushed no such tag; `_signature_exists`'s own replay check
37
+ and the `signature_ref` this workflow records both assume one exists.
38
+ `--registry-referrers-mode=legacy` restores it. `cosign verify` needs no
39
+ matching flag: it already looks for the tag by default.
40
+
11
41
  ## 1.9.9
12
42
 
13
43
  - **cosign gets the same registry credential the build pushed with**
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: code_sandboxes
3
- Version: 1.9.9
3
+ Version: 1.9.11
4
4
  Project-URL: Home, https://github.com/datalayer/code-sandboxes
5
5
  Author-email: Datalayer <info@datalayer.io>
6
6
  License: BSD 3-Clause License
@@ -3,4 +3,4 @@
3
3
 
4
4
  """Code Sandboxes."""
5
5
 
6
- __version__ = "1.9.9"
6
+ __version__ = "1.9.11"
@@ -403,17 +403,28 @@ class Attestor:
403
403
  def sign(self, *, registry: str, repository: str, digest: str) -> tuple[str, bool]:
404
404
  """Sign the digest with the KMS key, unless it is signed already (E1-09).
405
405
 
406
- Answers the signature's reference and whether this call made it. A
407
- replay finds the existing signature: pushing a second one under the
408
- same tag is what immutable tags refuse, and it would be a second thing
409
- claiming to be Datalayer's word on the same artifact.
406
+ Answers the signature's own reference — the digest itself, which is
407
+ what `cosign verify --key <key>` takes, resolving the signature's
408
+ real location on its own — and whether this call made it.
409
+
410
+ A replay finds the existing signature by asking cosign whether *this*
411
+ key has already signed it, the same check the Operator itself will
412
+ make before starting a pod (`can_verify`): cosign 3.1.3 stores a
413
+ signature as an OCI 1.1 referrer, not the classic `sha256-<hex>.sig`
414
+ sidecar tag a first version of this method assumed (found live,
415
+ 2026-09-14, twice — `--registry-referrers-mode` only ever governed
416
+ *reading* referrers, never where `sign` writes one, so it changed
417
+ nothing the first time either). Signing twice would not error the way
418
+ it would have under the old tag (an OCI referrer is not an immutable
419
+ tag to collide with), but it would leave two things claiming to be
420
+ Datalayer's word on the same artifact, which `can_verify` first
421
+ avoids.
410
422
  """
411
423
  self.can_sign()
412
- tag = signature_tag(digest)
413
424
  reference = f"{registry}/{repository}@{digest}"
414
- if self._signature_exists(repository=repository, tag=tag):
415
- self._log(f"{digest} is signed already, under {tag}")
416
- return f"{registry}/{repository}:{tag}", False
425
+ if self.can_verify(reference):
426
+ self._log(f"{digest} is signed already")
427
+ return reference, False
417
428
  command = [
418
429
  self._cosign,
419
430
  "sign",
@@ -452,22 +463,21 @@ class Attestor:
452
463
  "cosign did not sign the artifact; its output says why",
453
464
  detail={"digest": digest, "exit": finished.returncode},
454
465
  )
455
- return f"{registry}/{repository}:{tag}", True
466
+ return reference, True
456
467
 
457
- def _signature_exists(self, *, repository: str, tag: str) -> bool:
458
- try:
459
- answer = self._client().describe_images(
460
- repositoryName=repository, imageIds=[{"imageTag": tag}]
461
- )
462
- except Exception as error:
463
- if _is_missing(error):
464
- return False
465
- raise EnvironmentsError(
466
- PROVIDER_ERROR,
467
- f"Whether {tag} is already signed could not be read: {error}",
468
- detail={"repository": repository, "tag": tag},
469
- ) from error
470
- return bool(answer.get("imageDetails"))
468
+ def can_verify(self, reference: str) -> bool:
469
+ """Whether cosign already finds a signature by this key on `reference`.
470
+
471
+ Wherever cosign itself keeps a signature — the OCI 1.1 referrer it
472
+ defaults to, or the legacy sidecar tag an older registry might still
473
+ need — is cosign's own business to resolve; asking it directly, the
474
+ same check the Operator makes before starting a pod, is simpler and
475
+ more honest than tracking cosign's own storage choices here too.
476
+ """
477
+ finished = self._invoke(
478
+ [self._cosign, "verify", "--insecure-ignore-tlog=true", "--key", self._key, reference]
479
+ )
480
+ return finished.returncode == 0
471
481
 
472
482
  def _invoke(self, command: Sequence[str]) -> subprocess.CompletedProcess[str]:
473
483
  # `registry_auth` — same shape as the resolver's own — puts cosign's
@@ -88,7 +88,6 @@ class FakeEcr:
88
88
  statuses=("ACTIVE",),
89
89
  findings=(),
90
90
  enhanced_findings=True,
91
- signed: set[str] | None = None,
92
91
  manifest: dict | None = None,
93
92
  pages: list[list[dict]] | None = None,
94
93
  ) -> None:
@@ -99,11 +98,9 @@ class FakeEcr:
99
98
  #: `findings` when given, to test reading more than one page.
100
99
  self.pages = pages
101
100
  self.enhanced_findings = enhanced_findings
102
- self.signed = set(signed or set())
103
101
  self.manifest = manifest
104
102
  self.asked = 0
105
103
  self.scanned: list[str] = []
106
- self.described_tags: list[str] = []
107
104
 
108
105
  def batch_get_image(self, repositoryName, imageIds, acceptedMediaTypes): # noqa: N803 - boto3's spelling
109
106
  manifest = self.manifest or {
@@ -157,28 +154,29 @@ class FakeEcr:
157
154
  },
158
155
  }
159
156
 
160
- def describe_images(self, repositoryName, imageIds): # noqa: N803 - boto3's spelling
161
- tag = imageIds[0].get("imageTag") or ""
162
- self.described_tags.append(tag)
163
- if tag in self.signed:
164
- return {"imageDetails": [{"imageTags": [tag]}]}
165
- error = Exception("ImageNotFoundException")
166
- error.response = {"Error": {"Code": "ImageNotFoundException"}}
167
- raise error
168
-
169
157
 
170
158
  class Cosign:
171
- """A cosign whose argv and env are read, and which can refuse."""
159
+ """Every cosign invocation, in order; `argv`/`env` are the last call's own.
160
+
161
+ `verify_returncode` is `sign`'s own upfront replay check (E1-09): 1 (not
162
+ signed yet) unless a test says otherwise, so the ordinary path — verify,
163
+ then sign — still leaves `argv`/`env` as the `sign` call a test written
164
+ against the single-call fake already expects.
165
+ """
172
166
 
173
- def __init__(self, returncode: int = 0) -> None:
167
+ def __init__(self, returncode: int = 0, *, verify_returncode: int = 1) -> None:
174
168
  self.returncode = returncode
169
+ self.verify_returncode = verify_returncode
170
+ self.calls: list[tuple[list[str], dict[str, str] | None]] = []
175
171
  self.argv: list[str] = []
176
172
  self.env: dict[str, str] | None = None
177
173
 
178
174
  def __call__(self, argv, *, env=None, **_kwargs) -> subprocess.CompletedProcess[str]:
179
175
  self.argv = list(argv)
180
176
  self.env = env
181
- return subprocess.CompletedProcess(self.argv, self.returncode, "", "Pushing signature\n")
177
+ self.calls.append((self.argv, self.env))
178
+ code = self.verify_returncode if "verify" in argv else self.returncode
179
+ return subprocess.CompletedProcess(self.argv, code, "", "Pushing signature\n")
182
180
 
183
181
 
184
182
  def an_attestor(**changes) -> Attestor:
@@ -470,8 +468,17 @@ class TestTheSignature:
470
468
  KEY,
471
469
  f"{REGISTRY}/{REPOSITORY}@{DIGEST}",
472
470
  ]
473
- assert reference == f"{REGISTRY}/{REPOSITORY}:{signature_tag(DIGEST)}"
471
+ # The digest itself: what `cosign verify --key <key>` takes, not a
472
+ # tag — cosign 3.1.3 defaults to storing a signature as an OCI 1.1
473
+ # referrer, not the classic `sha256-<hex>.sig` sidecar tag (found
474
+ # live 2026-09-14, twice: `--registry-referrers-mode` only ever
475
+ # governed *reading* referrers, never where `sign` writes one).
476
+ assert reference == f"{REGISTRY}/{REPOSITORY}@{DIGEST}"
474
477
  assert signed_now is True
478
+ # The upfront replay check, cosign's own answer for whether this key
479
+ # already signed it — not yet, here, so `sign` ran right after.
480
+ subcommands = [call[0][1] for call in cosign.calls]
481
+ assert subcommands == ["verify", "sign"]
475
482
 
476
483
  def test_no_registry_auth_leaves_cosigns_own_environment_untouched(self) -> None:
477
484
  """The common case — nothing to add — inherits this process's own
@@ -503,15 +510,19 @@ class TestTheSignature:
503
510
  assert cosign.env[name] == os.environ[name]
504
511
 
505
512
  def test_a_replay_finds_the_signature_instead_of_pushing_a_second(self) -> None:
506
- """Immutable tags would refuse the second, and two signatures are two words."""
507
- ecr = FakeEcr(signed={signature_tag(DIGEST)})
508
- cosign = Cosign()
509
- reference, signed_now = an_attestor(ecr=ecr, run=cosign).sign(
513
+ """A second signature would not error the way a second push under the
514
+ old immutable tag once did, but it would still be two things claiming
515
+ to be Datalayer's word on the same artifact — cosign's own answer to
516
+ `verify` is asked first, and `sign` never runs when it says yes."""
517
+ cosign = Cosign(verify_returncode=0)
518
+ reference, signed_now = an_attestor(run=cosign).sign(
510
519
  registry=REGISTRY, repository=REPOSITORY, digest=DIGEST
511
520
  )
512
521
  assert signed_now is False
513
- assert cosign.argv == []
514
- assert reference.endswith(signature_tag(DIGEST))
522
+ assert len(cosign.calls) == 1
523
+ assert "verify" in cosign.argv
524
+ assert "sign" not in cosign.argv
525
+ assert reference == f"{REGISTRY}/{REPOSITORY}@{DIGEST}"
515
526
 
516
527
  def test_cosign_refusing_is_a_provider_error(self) -> None:
517
528
  with pytest.raises(EnvironmentsError) as raised:
@@ -530,6 +541,23 @@ class TestTheSignature:
530
541
  an_attestor(cosign="").sign(registry=REGISTRY, repository=REPOSITORY, digest=DIGEST)
531
542
  assert raised.value.detail["missing"] == "cosign"
532
543
 
544
+ def test_can_verify_asks_cosign_and_answers_its_exit_code(self) -> None:
545
+ reference = f"{REGISTRY}/{REPOSITORY}@{DIGEST}"
546
+ assert an_attestor(run=Cosign(verify_returncode=0)).can_verify(reference) is True
547
+ assert an_attestor(run=Cosign(verify_returncode=1)).can_verify(reference) is False
548
+
549
+ def test_can_verify_names_the_key_and_ignores_the_transparency_log(self) -> None:
550
+ cosign = Cosign(verify_returncode=0)
551
+ an_attestor(run=cosign, key=KEY).can_verify(f"{REGISTRY}/{REPOSITORY}@{DIGEST}")
552
+ assert cosign.argv == [
553
+ "/usr/bin/cosign",
554
+ "verify",
555
+ "--insecure-ignore-tlog=true",
556
+ "--key",
557
+ KEY,
558
+ f"{REGISTRY}/{REPOSITORY}@{DIGEST}",
559
+ ]
560
+
533
561
  def test_the_signature_sits_beside_the_image_at_cosigns_own_tag(self) -> None:
534
562
  assert signature_tag(DIGEST) == "sha256-" + "aa" * 32 + ".sig"
535
563
  with pytest.raises(ValueError):
@@ -555,7 +583,7 @@ class TestAttestingAnArtifact:
555
583
  artifact=self.an_artifact(), size_bytes=116_183_040, attestor=attestor
556
584
  )
557
585
  assert answer["scan_summary"]["decision"] == "pass"
558
- assert answer["signature_ref"].endswith(signature_tag(DIGEST))
586
+ assert answer["signature_ref"] == f"{REGISTRY}/{REPOSITORY}@{DIGEST}"
559
587
  assert answer["sbom_ref"].endswith(".sbom")
560
588
  assert answer["provenance_ref"].endswith(".att")
561
589
  assert answer["size_bytes"] == 116_183_040
File without changes
File without changes