openenv-openshell 0.1.1__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 (130) hide show
  1. openenv_openshell-0.1.1/.gitignore +35 -0
  2. openenv_openshell-0.1.1/LICENSE +202 -0
  3. openenv_openshell-0.1.1/Makefile +59 -0
  4. openenv_openshell-0.1.1/PKG-INFO +296 -0
  5. openenv_openshell-0.1.1/README.md +269 -0
  6. openenv_openshell-0.1.1/SPEC.md +2195 -0
  7. openenv_openshell-0.1.1/docs/_hooks/readme.py +48 -0
  8. openenv_openshell-0.1.1/docs/architecture.md +177 -0
  9. openenv_openshell-0.1.1/docs/beads-worktrees.md +68 -0
  10. openenv_openshell-0.1.1/docs/cleanup-tests.md +142 -0
  11. openenv_openshell-0.1.1/docs/coding-agent-demo.md +116 -0
  12. openenv_openshell-0.1.1/docs/compatibility-matrix.md +108 -0
  13. openenv_openshell-0.1.1/docs/configuration.md +250 -0
  14. openenv_openshell-0.1.1/docs/documentation.md +141 -0
  15. openenv_openshell-0.1.1/docs/echo-env-image.md +273 -0
  16. openenv_openshell-0.1.1/docs/examples/gateway-vm.toml +9 -0
  17. openenv_openshell-0.1.1/docs/examples/remote-gateway-bootstrap.sh +65 -0
  18. openenv_openshell-0.1.1/docs/examples/remote-oidc-gateway-bootstrap.sh +108 -0
  19. openenv_openshell-0.1.1/docs/getting-started.md +7 -0
  20. openenv_openshell-0.1.1/docs/image-startup.md +126 -0
  21. openenv_openshell-0.1.1/docs/images.md +83 -0
  22. openenv_openshell-0.1.1/docs/index.md +45 -0
  23. openenv_openshell-0.1.1/docs/integration-ci.md +101 -0
  24. openenv_openshell-0.1.1/docs/lifecycle-spike.md +95 -0
  25. openenv_openshell-0.1.1/docs/local-openshell-testing.md +235 -0
  26. openenv_openshell-0.1.1/docs/openenv-compatibility.md +142 -0
  27. openenv_openshell-0.1.1/docs/openshell-sdk-contract.md +406 -0
  28. openenv_openshell-0.1.1/docs/process-capacity.md +52 -0
  29. openenv_openshell-0.1.1/docs/protocol-spike.md +284 -0
  30. openenv_openshell-0.1.1/docs/provider-acceptance.md +64 -0
  31. openenv_openshell-0.1.1/docs/release-notes/0.1.0.md +95 -0
  32. openenv_openshell-0.1.1/docs/release-notes/0.1.1.md +20 -0
  33. openenv_openshell-0.1.1/docs/releases.md +298 -0
  34. openenv_openshell-0.1.1/docs/remote-gateway-testing.md +132 -0
  35. openenv_openshell-0.1.1/docs/repository-publication.md +82 -0
  36. openenv_openshell-0.1.1/docs/security-review.md +111 -0
  37. openenv_openshell-0.1.1/docs/security.md +247 -0
  38. openenv_openshell-0.1.1/docs/spike-decisions.md +64 -0
  39. openenv_openshell-0.1.1/docs/troubleshooting.md +156 -0
  40. openenv_openshell-0.1.1/examples/coding-agent/Dockerfile +40 -0
  41. openenv_openshell-0.1.1/examples/coding-agent/policy.yaml +34 -0
  42. openenv_openshell-0.1.1/examples/coding_env.py +252 -0
  43. openenv_openshell-0.1.1/examples/policies/README.md +119 -0
  44. openenv_openshell-0.1.1/examples/policies/deny-all.yaml +24 -0
  45. openenv_openshell-0.1.1/examples/policies/hf-minimal.yaml +35 -0
  46. openenv_openshell-0.1.1/examples/policies/image-compatible.yaml +20 -0
  47. openenv_openshell-0.1.1/examples/quickstart.py +52 -0
  48. openenv_openshell-0.1.1/pyproject.toml +132 -0
  49. openenv_openshell-0.1.1/requirements-openshell.txt +2 -0
  50. openenv_openshell-0.1.1/scripts/__init__.py +1 -0
  51. openenv_openshell-0.1.1/scripts/check-openshell-local.sh +164 -0
  52. openenv_openshell-0.1.1/scripts/check_distribution.py +126 -0
  53. openenv_openshell-0.1.1/scripts/check_sdk_prerequisite.py +49 -0
  54. openenv_openshell-0.1.1/scripts/release_gate.py +66 -0
  55. openenv_openshell-0.1.1/src/openenv_openshell/__init__.py +30 -0
  56. openenv_openshell-0.1.1/src/openenv_openshell/_adapter.py +139 -0
  57. openenv_openshell-0.1.1/src/openenv_openshell/_compat.py +7 -0
  58. openenv_openshell-0.1.1/src/openenv_openshell/_naming.py +4 -0
  59. openenv_openshell-0.1.1/src/openenv_openshell/_sdk.py +324 -0
  60. openenv_openshell-0.1.1/src/openenv_openshell/config.py +249 -0
  61. openenv_openshell-0.1.1/src/openenv_openshell/errors.py +37 -0
  62. openenv_openshell-0.1.1/src/openenv_openshell/metadata.py +50 -0
  63. openenv_openshell-0.1.1/src/openenv_openshell/policy.py +108 -0
  64. openenv_openshell-0.1.1/src/openenv_openshell/provider.py +495 -0
  65. openenv_openshell-0.1.1/src/openenv_openshell/py.typed +1 -0
  66. openenv_openshell-0.1.1/tests/__init__.py +1 -0
  67. openenv_openshell-0.1.1/tests/fakes.py +187 -0
  68. openenv_openshell-0.1.1/tests/fixtures/openshell-0.1.2.json +153 -0
  69. openenv_openshell-0.1.1/tests/integration/README.md +455 -0
  70. openenv_openshell-0.1.1/tests/integration/__init__.py +1 -0
  71. openenv_openshell-0.1.1/tests/integration/_ci.py +101 -0
  72. openenv_openshell-0.1.1/tests/integration/_lifecycle_spike.py +210 -0
  73. openenv_openshell-0.1.1/tests/integration/_runtime.py +114 -0
  74. openenv_openshell-0.1.1/tests/integration/conftest.py +56 -0
  75. openenv_openshell-0.1.1/tests/integration/images/echo/Dockerfile +28 -0
  76. openenv_openshell-0.1.1/tests/integration/images/echo/Dockerfile.docker-driver +7 -0
  77. openenv_openshell-0.1.1/tests/integration/images/echo/local-image-id.txt +1 -0
  78. openenv_openshell-0.1.1/tests/integration/images/echo/policy.yaml +20 -0
  79. openenv_openshell-0.1.1/tests/integration/images/echo/remote-image-ref.txt +1 -0
  80. openenv_openshell-0.1.1/tests/integration/images/filesystem/Dockerfile +10 -0
  81. openenv_openshell-0.1.1/tests/integration/images/prerequisites/Dockerfile +8 -0
  82. openenv_openshell-0.1.1/tests/integration/test_cleanup_ownership.py +117 -0
  83. openenv_openshell-0.1.1/tests/integration/test_coding_demo.py +55 -0
  84. openenv_openshell-0.1.1/tests/integration/test_echo_image.py +157 -0
  85. openenv_openshell-0.1.1/tests/integration/test_filesystem_security.py +109 -0
  86. openenv_openshell-0.1.1/tests/integration/test_http_readiness.py +46 -0
  87. openenv_openshell-0.1.1/tests/integration/test_image_startup.py +41 -0
  88. openenv_openshell-0.1.1/tests/integration/test_lifecycle_spike.py +15 -0
  89. openenv_openshell-0.1.1/tests/integration/test_managed_credentials.py +194 -0
  90. openenv_openshell-0.1.1/tests/integration/test_network_security.py +111 -0
  91. openenv_openshell-0.1.1/tests/integration/test_openenv_client.py +185 -0
  92. openenv_openshell-0.1.1/tests/integration/test_policy_before_execution.py +132 -0
  93. openenv_openshell-0.1.1/tests/integration/test_protocol_spike.py +180 -0
  94. openenv_openshell-0.1.1/tests/integration/test_provider_startup.py +223 -0
  95. openenv_openshell-0.1.1/tests/integration/test_quickstart.py +39 -0
  96. openenv_openshell-0.1.1/tests/integration/test_runtime_fixture.py +41 -0
  97. openenv_openshell-0.1.1/tests/integration/test_security_review.py +107 -0
  98. openenv_openshell-0.1.1/tests/openenv_client.py +120 -0
  99. openenv_openshell-0.1.1/tests/unit/__init__.py +1 -0
  100. openenv_openshell-0.1.1/tests/unit/conftest.py +56 -0
  101. openenv_openshell-0.1.1/tests/unit/test_adapter.py +403 -0
  102. openenv_openshell-0.1.1/tests/unit/test_adapter_contract.py +136 -0
  103. openenv_openshell-0.1.1/tests/unit/test_cleanup.py +387 -0
  104. openenv_openshell-0.1.1/tests/unit/test_cleanup_sdk.py +181 -0
  105. openenv_openshell-0.1.1/tests/unit/test_close.py +131 -0
  106. openenv_openshell-0.1.1/tests/unit/test_compatibility.py +56 -0
  107. openenv_openshell-0.1.1/tests/unit/test_config.py +339 -0
  108. openenv_openshell-0.1.1/tests/unit/test_create_request.py +239 -0
  109. openenv_openshell-0.1.1/tests/unit/test_distribution.py +49 -0
  110. openenv_openshell-0.1.1/tests/unit/test_fakes.py +159 -0
  111. openenv_openshell-0.1.1/tests/unit/test_integration_ci.py +84 -0
  112. openenv_openshell-0.1.1/tests/unit/test_lifecycle_spike.py +153 -0
  113. openenv_openshell-0.1.1/tests/unit/test_observability.py +208 -0
  114. openenv_openshell-0.1.1/tests/unit/test_openenv_client.py +262 -0
  115. openenv_openshell-0.1.1/tests/unit/test_openshell_contract.py +98 -0
  116. openenv_openshell-0.1.1/tests/unit/test_package.py +36 -0
  117. openenv_openshell-0.1.1/tests/unit/test_policy.py +199 -0
  118. openenv_openshell-0.1.1/tests/unit/test_policy_examples.py +128 -0
  119. openenv_openshell-0.1.1/tests/unit/test_policy_provenance.py +212 -0
  120. openenv_openshell-0.1.1/tests/unit/test_protocol_probe.py +64 -0
  121. openenv_openshell-0.1.1/tests/unit/test_quickstart_docs.py +28 -0
  122. openenv_openshell-0.1.1/tests/unit/test_readiness.py +333 -0
  123. openenv_openshell-0.1.1/tests/unit/test_release_gate.py +59 -0
  124. openenv_openshell-0.1.1/tests/unit/test_runtime_fixture.py +134 -0
  125. openenv_openshell-0.1.1/tests/unit/test_sdk_prerequisite.py +64 -0
  126. openenv_openshell-0.1.1/tests/unit/test_secret_safety.py +164 -0
  127. openenv_openshell-0.1.1/tests/unit/test_start_container.py +357 -0
  128. openenv_openshell-0.1.1/tests/unit/test_startup_failures.py +231 -0
  129. openenv_openshell-0.1.1/tests/unit/test_successful_lifecycle.py +278 -0
  130. openenv_openshell-0.1.1/uv.lock +3459 -0
@@ -0,0 +1,35 @@
1
+ .coverage
2
+ .DS_Store
3
+ .pytest_cache/
4
+ .ruff_cache/
5
+ .venv/
6
+ .vscode/
7
+ __pycache__/
8
+ build/
9
+ dist/
10
+ htmlcov/
11
+ *.egg-info/
12
+ *.py[cod]
13
+
14
+ # Keep shared Codex setup; ignore other local Codex files.
15
+ /.codex/*
16
+ !/.codex/config.toml
17
+ !/.codex/hooks.json
18
+ !/.codex/environments/
19
+ /.codex/environments/*
20
+ !/.codex/environments/environment.toml
21
+
22
+
23
+ # Beads / Dolt files (added by bd init)
24
+ .dolt/
25
+ *.db
26
+ .beads-credential-key
27
+ .beads/proxieddb/
28
+ *.gate.lock*
29
+
30
+ # MkDocs generated manual
31
+ /site/
32
+
33
+ # Local agent worktrees and plugins
34
+ .claude/worktrees/
35
+ plugins/
@@ -0,0 +1,202 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ To apply the Apache License to your work, attach the following
181
+ boilerplate notice, with the fields enclosed by brackets "[]"
182
+ replaced with your own identifying information. (Don't include
183
+ the brackets!) The text should be enclosed in the appropriate
184
+ comment syntax for the file format. We also recommend that a
185
+ file or class name and description of purpose be included on the
186
+ same "printed page" as the copyright notice for easier
187
+ identification within third-party archives.
188
+
189
+ Copyright [yyyy] [name of copyright owner]
190
+
191
+ Licensed under the Apache License, Version 2.0 (the "License");
192
+ you may not use this file except in compliance with the License.
193
+ You may obtain a copy of the License at
194
+
195
+ http://www.apache.org/licenses/LICENSE-2.0
196
+
197
+ Unless required by applicable law or agreed to in writing, software
198
+ distributed under the License is distributed on an "AS IS" BASIS,
199
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
+ See the License for the specific language governing permissions and
201
+ limitations under the License.
202
+
@@ -0,0 +1,59 @@
1
+ .PHONY: docs-build docs-serve check compatibility demo format integration lint openshell-prereqs openshell-smoke security-e2e security-filesystem security-network test typecheck
2
+
3
+ export OPENENV_OPENSHELL_FILESYSTEM_IMAGE_ID OPENENV_OPENSHELL_NETWORK_IMAGE_ID OPENENV_OPENSHELL_CODING_IMAGE_ID
4
+
5
+ check: lint typecheck test
6
+
7
+ compatibility:
8
+ uv run --locked pytest --no-cov tests/unit/test_compatibility.py tests/unit/test_openenv_client.py tests/unit/test_openshell_contract.py tests/unit/test_adapter_contract.py tests/unit/test_adapter.py
9
+
10
+ format:
11
+ uv run ruff format .
12
+ uv run ruff check --fix .
13
+
14
+ lint:
15
+ uv run ruff format --check .
16
+ uv run ruff check .
17
+
18
+ typecheck:
19
+ uv run pyright
20
+
21
+ test:
22
+ uv run pytest
23
+
24
+ integration:
25
+ uv run pytest -m integration
26
+
27
+ # Explicit jobs must fail on missing opt-in rather than report skipped tests.
28
+ # Separate images prevent accidentally using EchoEnv without the SEC5 canaries.
29
+ security-filesystem:
30
+ @test -n "$$OPENENV_OPENSHELL_FILESYSTEM_IMAGE_ID" || { echo "Set OPENENV_OPENSHELL_FILESYSTEM_IMAGE_ID to the SEC5 canary image" >&2; exit 2; }
31
+ OPENENV_OPENSHELL_ECHO_IMAGE_ID="$$OPENENV_OPENSHELL_FILESYSTEM_IMAGE_ID" uv run pytest -m integration --no-cov tests/integration/test_filesystem_security.py -v
32
+
33
+ security-network:
34
+ @test -n "$$OPENENV_OPENSHELL_NETWORK_IMAGE_ID" || { echo "Set OPENENV_OPENSHELL_NETWORK_IMAGE_ID to the validated EchoEnv image" >&2; exit 2; }
35
+ OPENENV_OPENSHELL_ECHO_IMAGE_ID="$$OPENENV_OPENSHELL_NETWORK_IMAGE_ID" uv run pytest -m integration --no-cov tests/integration/test_network_security.py -v
36
+
37
+ # Check both inputs before creating any sandbox; run the jobs sequentially.
38
+ security-e2e:
39
+ @test -n "$$OPENENV_OPENSHELL_FILESYSTEM_IMAGE_ID" && test -n "$$OPENENV_OPENSHELL_NETWORK_IMAGE_ID" || { echo "Set both security job image variables; see tests/integration/README.md" >&2; exit 2; }
40
+ $(MAKE) security-filesystem
41
+ $(MAKE) security-network
42
+
43
+ # I8 reference demo; see docs/coding-agent-demo.md for the image build.
44
+ demo:
45
+ @test -n "$$OPENENV_OPENSHELL_CODING_IMAGE_ID" || { echo "Set OPENENV_OPENSHELL_CODING_IMAGE_ID; see docs/coding-agent-demo.md" >&2; exit 2; }
46
+ uv run python examples/coding_env.py
47
+
48
+ openshell-prereqs:
49
+ ./scripts/check-openshell-local.sh
50
+
51
+ openshell-smoke:
52
+ ./scripts/check-openshell-local.sh --smoke
53
+
54
+ # Docs-only commands do not install or execute the runtime dependencies.
55
+ docs-build:
56
+ uv run --locked --only-group docs mkdocs build --strict
57
+
58
+ docs-serve:
59
+ uv run --locked --only-group docs mkdocs serve
@@ -0,0 +1,296 @@
1
+ Metadata-Version: 2.5
2
+ Name: openenv-openshell
3
+ Version: 0.1.1
4
+ Summary: Run OpenEnv environment servers in NVIDIA OpenShell sandboxes
5
+ Project-URL: Repository, https://github.com/rodrigosetti/openenv-openshell
6
+ Project-URL: Issues, https://github.com/rodrigosetti/openenv-openshell/issues
7
+ Project-URL: Documentation, https://rodrigosetti.github.io/openenv-openshell/
8
+ Project-URL: Source documentation, https://github.com/rodrigosetti/openenv-openshell/tree/main/docs
9
+ Project-URL: Changelog, https://github.com/rodrigosetti/openenv-openshell/blob/main/docs/release-notes/0.1.1.md
10
+ Author: OpenEnv OpenShell contributors
11
+ License-Expression: Apache-2.0
12
+ License-File: LICENSE
13
+ Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: Apache Software License
16
+ Classifier: Programming Language :: Python :: 3 :: Only
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Programming Language :: Python :: 3.14
21
+ Classifier: Typing :: Typed
22
+ Requires-Python: >=3.11
23
+ Requires-Dist: httpx<0.29,>=0.28
24
+ Requires-Dist: openenv==0.10.0
25
+ Requires-Dist: pyyaml<7,>=6.0.3
26
+ Description-Content-Type: text/markdown
27
+
28
+ # openenv-openshell
29
+
30
+ `openenv-openshell` runs Hugging Face [OpenEnv](https://github.com/huggingface/OpenEnv)
31
+ environment servers inside NVIDIA [OpenShell](https://github.com/NVIDIA/OpenShell)
32
+ sandboxes, under OpenShell filesystem, network, and credential policies. It
33
+ implements OpenEnv's `ContainerProvider` interface, so existing OpenEnv clients
34
+ and training loops keep working: you swap the provider, not the client.
35
+
36
+ ```python
37
+ env = GenericEnvClient.from_docker_image(image, provider=OpenShellProvider(...)).sync()
38
+ ```
39
+
40
+ **Restricted single-tenant alpha; v0.1.1 prepared for PyPI.** The provider
41
+ lifecycle, explicit policies, and cleanup are implemented and validated on a
42
+ local OpenShell 0.1.2 gateway with OpenEnv 0.10.0. This alpha is supported only
43
+ when one trusted operator exclusively controls the OpenShell gateway and
44
+ workspace. It is not upstream-endorsed, and it is not safe for shared,
45
+ multi-tenant, independently administered, or hostile-tenant deployments. See
46
+ [known limitations](#known-limitations) before relying on it. The
47
+ [v0.1.1 release notes](docs/release-notes/0.1.1.md) describe the restricted
48
+ release boundary; M2/M3/I14 remain the path to a broadly supported release.
49
+
50
+ ## Requirements
51
+
52
+ - Python 3.11+.
53
+ - An OpenShell **0.1.2** CLI and gateway with a working compute driver. Follow
54
+ the [local OpenShell setup](docs/local-openshell-testing.md); on Apple Silicon
55
+ this is the native VM driver. `openshell status` must show the gateway
56
+ connected at version 0.1.2.
57
+ - The OpenShell 0.1.2 Python SDK (installed below; the `openshell` package on
58
+ PyPI is a different, incompatible release).
59
+ - Docker, to build the example images.
60
+
61
+ ## Install
62
+
63
+ From a checkout (includes the SDK and dev tools):
64
+
65
+ ```bash
66
+ git clone https://github.com/rodrigosetti/openenv-openshell.git
67
+ cd openenv-openshell
68
+ uv sync --locked --all-groups
69
+ ```
70
+
71
+ Into an existing virtual environment:
72
+
73
+ ```bash
74
+ pip install "openenv-openshell @ git+https://github.com/rodrigosetti/openenv-openshell"
75
+ pip install 'openshell @ https://github.com/NVIDIA/OpenShell/releases/download/v0.1.2/openshell-0.1.2-py3-none-any.whl#sha256=8c409da4f176d42418d92366fe201f47cceef2c0fa432bfbce2bf938649d59cf'
76
+ ```
77
+
78
+ The provider rejects any SDK version other than 0.1.2 before contacting a
79
+ gateway. See [SDK installation](docs/releases.md#sdk-and-gateway-prerequisites).
80
+
81
+ ## Quickstart
82
+
83
+ Run the upstream EchoEnv server in an OpenShell sandbox and talk to it with the
84
+ unmodified OpenEnv client. From the repository root, with the gateway running:
85
+
86
+ ```bash
87
+ # 1. Build the pinned EchoEnv image (native arm64 for the local VM driver).
88
+ docker build -t openenv-openshell-echo:quickstart \
89
+ -f tests/integration/images/echo/Dockerfile tests/integration/images/echo
90
+ export OPENENV_OPENSHELL_ECHO_IMAGE_ID="$(docker image inspect --format '{{.Id}}' openenv-openshell-echo:quickstart)"
91
+
92
+ # 2. Run the quickstart.
93
+ uv run python examples/quickstart.py
94
+ ```
95
+
96
+ Expected output (the sandbox name is random):
97
+
98
+ ```text
99
+ echo: hello from OpenShell
100
+ steps: 1
101
+ sandbox: openenv-sha2-d91afc
102
+ deleted: True
103
+ ```
104
+
105
+ [`examples/quickstart.py`](examples/quickstart.py) is the whole program:
106
+
107
+ ```python
108
+ import os
109
+
110
+ from openenv.core.generic_client import GenericEnvClient
111
+
112
+ from openenv_openshell import OpenShellProvider
113
+
114
+ provider = OpenShellProvider(
115
+ # Required for this restricted alpha's automatic, name-based cleanup.
116
+ # Use only for an exclusive gateway/workspace controlled by one trusted operator.
117
+ restricted_alpha_cleanup_acknowledged=True,
118
+ # Exact server argv; OpenShell 0.1.2 does not run the image CMD for you.
119
+ command=[
120
+ "sh",
121
+ "-c",
122
+ "cd /app/env && uvicorn server.app:app --host 0.0.0.0 --port 8000",
123
+ ],
124
+ service_port=8000,
125
+ policy="examples/policies/image-compatible.yaml",
126
+ labels={"openenv.environment": "echo"},
127
+ )
128
+ image = os.environ["OPENENV_OPENSHELL_ECHO_IMAGE_ID"]
129
+ env = GenericEnvClient.from_docker_image(image, provider=provider).sync()
130
+ with env:
131
+ env.reset()
132
+ result = env.step(
133
+ {
134
+ "type": "call_tool",
135
+ "tool_name": "echo_message",
136
+ "arguments": {"message": "hello from OpenShell"},
137
+ }
138
+ )
139
+ print("echo:", result.observation["result"]["data"])
140
+ print("steps:", env.state()["step_count"])
141
+ print("sandbox:", provider.metadata and provider.metadata.sandbox_name)
142
+ print("deleted:", provider.state.deleted)
143
+ ```
144
+
145
+ This quickstart is only for the restricted-alpha boundary: before running it,
146
+ ensure no independent or hostile actor can create or reuse sandbox names in
147
+ this gateway/workspace. The acknowledgement does not make deletion atomic;
148
+ it records that you accept the remaining risk. For a shared gateway, do not
149
+ run this alpha—use `keep_sandbox=True` only for manual operator cleanup, or
150
+ wait for the later atomic-deletion release.
151
+
152
+ What happens: the provider validates the command and policy offline, creates
153
+ the sandbox with the policy and service route in one request, waits for
154
+ OpenShell and then `/health`, and hands OpenEnv the routed URL. The client
155
+ connects over WebSocket. Leaving the `with` block deletes the sandbox and waits
156
+ until it is gone; a failed start is rolled back the same way.
157
+
158
+ To adapt it to your own environment image, change `command`, `service_port`,
159
+ `policy`, and any `env_vars` the server needs. OpenShell 0.1.2 does not use
160
+ the image's `CMD`, `WORKDIR`, or `ENV`. Read the
161
+ [image guide](docs/images.md) and pin the image by digest.
162
+
163
+ Something wrong? See [troubleshooting](docs/troubleshooting.md).
164
+
165
+ ## Coding-agent demo
166
+
167
+ The canonical demo runs the upstream OpenEnv coding environment under a strict
168
+ policy: it solves a task over the OpenEnv WebSocket, writes to `/workspace`,
169
+ reaches `pypi.org`, is denied `~/.ssh`, `/host`, and `example.com`, keeps the
170
+ session working, and deletes the sandbox.
171
+
172
+ ```bash
173
+ docker build -t openenv-openshell-coding:i8 examples/coding-agent
174
+ export OPENENV_OPENSHELL_CODING_IMAGE_ID="$(docker image inspect --format '{{.Id}}' openenv-openshell-coding:i8)"
175
+ make demo
176
+ ```
177
+
178
+ ```text
179
+ ✓ OpenShell sandbox created (oe-demo-e531c976, policy 5104817a61fe)
180
+ ✓ OpenEnv server healthy
181
+ ✓ WebSocket connected
182
+ ✓ task executed (fizzbuzz via OpenEnv coding_env)
183
+ ✓ approved filesystem access succeeded (/workspace)
184
+ ✓ forbidden filesystem access denied (~/.ssh, /host)
185
+ ✓ approved package index request succeeded (pypi.org)
186
+ ✓ forbidden network request denied (example.com)
187
+ ✓ OpenEnv session still healthy after denials
188
+ ✓ sandbox deleted
189
+ ```
190
+
191
+ The gateway needs internet access to `pypi.org` and `example.com`. The
192
+ [demo guide](docs/coding-agent-demo.md) explains each check and its limits.
193
+
194
+ ## Documentation
195
+
196
+ Read the [searchable user manual](https://rodrigosetti.github.io/openenv-openshell/)
197
+ or browse the [source guides](docs/index.md). Preview locally with `make docs-serve` at
198
+ `http://127.0.0.1:8000/openenv-openshell/`. See
199
+ [documentation contributions](docs/documentation.md) for the locked docs-only
200
+ installation, strict build, and GitHub Pages deployment procedure.
201
+
202
+ | Guide | Contents |
203
+ | --- | --- |
204
+ | [Configuration reference](docs/configuration.md) | Every provider option, start arguments, policy, credentials, resources, metadata, errors, logging |
205
+ | [Images](docs/images.md) | Preparing images for OpenShell and pinning them immutably |
206
+ | [Troubleshooting](docs/troubleshooting.md) | Errors by symptom, diagnostics, cleanup |
207
+ | [Policy examples](examples/policies/README.md) | Strict, Hugging Face read-only, and image-compatible policies |
208
+ | [Architecture](docs/architecture.md) | Lifecycle, routing, failure recovery, metadata |
209
+ | [Security](docs/security.md) | Policy precedence, credentials, enforcement evidence, residual risks |
210
+ | [Compatibility matrix](docs/compatibility-matrix.md) | Supported OpenEnv, SDK, and gateway versions |
211
+ | [Local OpenShell setup](docs/local-openshell-testing.md) | Installing and checking the gateway and VM driver |
212
+
213
+ [SPEC.md](SPEC.md) holds the requirements and milestones.
214
+
215
+ ## Known limitations
216
+
217
+ - Only OpenEnv 0.10.0 and OpenShell SDK/gateway 0.1.2 are supported.
218
+ The OpenEnv pin includes automatic cleanup when the async factory is cancelled
219
+ during its initial WebSocket connection. Failed cleanup still needs an explicit
220
+ retry or operator inspection; see the [cancellation contract](docs/openenv-compatibility.md#async-factory-cancellation).
221
+ - Validated on the local native arm64 VM driver with locally built images. Their
222
+ image IDs are not pullable registry digests. S5b also validated a digest-pinned
223
+ amd64 EchoEnv image on a remote Docker driver with OIDC; arbitrary images and
224
+ other compute drivers are unverified.
225
+ - Remote gateways using the standard mTLS configuration are **not supported**
226
+ for unmodified OpenEnv clients: service routes require a TLS client
227
+ certificate the client cannot present. The provider fails with
228
+ `ServiceAccessError` instead of timing out. S5b validated an OIDC-configured
229
+ remote gateway with the unmodified async/sync client: lifecycle RPCs required
230
+ a bearer token, but service routes were anonymous within the IP-restricted
231
+ network boundary. OIDC gateway authentication does not protect those service
232
+ routes. Edge authentication, HTTP 401/403 service challenges, long idle
233
+ sessions, and reconnects remain unverified. See
234
+ [S5b remote evidence](docs/protocol-spike.md#oidc-remote-gateway-validation-s5b-2026-10-01).
235
+ - You must supply the server command, environment, and working directory; OCI
236
+ `ENTRYPOINT`/`CMD`, `ENV`, and `WORKDIR` are not resolved.
237
+ - Security milestones are incomplete: name-based cleanup can affect a sandbox
238
+ that replaces it between identity lookup and deletion (SEC8c), and the local VM
239
+ lane offers no process-capacity
240
+ isolation against hostile workloads. This restricted alpha therefore requires
241
+ `restricted_alpha_cleanup_acknowledged=True` before it starts an automatically
242
+ cleaned workload, and supports only a trusted operator's exclusive
243
+ gateway/workspace. Random names, labels, locks, lookup checks, and
244
+ identity-aware waits are mitigations, not atomic deletion. Do not use it on a
245
+ shared or multi-tenant gateway. It neither resolves SEC8c nor represents
246
+ OpenEnv or NVIDIA endorsement. See the [security guide](docs/security.md).
247
+
248
+ ## Development
249
+
250
+ ```bash
251
+ uv sync --locked --all-groups
252
+ make check # Ruff format/lint, strict Pyright, unit tests with ≥95% branch coverage
253
+ ```
254
+
255
+ Unit tests use typed fakes and need no OpenShell installation or gateway. Tests
256
+ that need a real gateway are marked `integration`, live in `tests/integration`,
257
+ and are opt-in:
258
+
259
+ ```bash
260
+ make openshell-prereqs # CLI/gateway versions and workspace access
261
+ make openshell-smoke # disposable sandbox with an HTTP service route
262
+ OPENENV_OPENSHELL_ECHO_IMAGE_ID=... uv run pytest -m integration --no-cov tests/integration/test_quickstart.py
263
+ make integration # every opt-in runtime test
264
+ make security-e2e # filesystem and network denial jobs
265
+ ```
266
+
267
+ The [integration guide](tests/integration/README.md) lists each suite and its
268
+ image inputs; [integration CI](docs/integration-ci.md) covers the gated runner.
269
+
270
+ The [Quality workflow](.github/workflows/quality.yml) runs `make check` and
271
+ builds the sdist and wheel on Python 3.11 through 3.14. To reproduce one job:
272
+
273
+ ```bash
274
+ export UV_PYTHON=3.12 UV_LOCKED=true
275
+ uv lock --check
276
+ uv sync --locked --all-groups
277
+ make check
278
+ uv build --no-build-isolation
279
+ ```
280
+
281
+ Release preparation is described in [releases](docs/releases.md). Acceptance
282
+ evidence for each milestone is recorded in
283
+ [M0](docs/protocol-spike.md#m0-acceptance-verification-2026-09-30),
284
+ [M1](docs/provider-acceptance.md), the
285
+ [OpenEnv client check](docs/openenv-compatibility.md), and the
286
+ [security review](docs/security-review.md). The
287
+ [Codex local environment](.codex/environments/environment.toml) runs
288
+ `uv sync --locked --all-groups` for new worktrees.
289
+
290
+ The public repository is
291
+ [rodrigosetti/openenv-openshell](https://github.com/rodrigosetti/openenv-openshell);
292
+ see the [publication guide](docs/repository-publication.md).
293
+
294
+ ## License
295
+
296
+ Apache-2.0; see [LICENSE](LICENSE).