@@ -168,31 +168,32 @@ def _get_allowed_write_folders(render_context: RenderContext) -> list[str]:
168168 ctx .get_current_conformance_test_folder_name (),
169169 )
170170 folders .append (os .path .normpath (os .path .abspath (folder )))
171- elif render_context .conformance_tests_folder :
172- folders .append (os .path .normpath (os .path .abspath (render_context .conformance_tests_folder )))
171+ elif render_context .should_run_conformance_tests ():
172+ module_tests_folder = render_context .conformance_tests .get_module_conformance_tests_folder (
173+ render_context .module_name
174+ )
175+ folders .append (os .path .normpath (os .path .abspath (module_tests_folder )))
173176
174177 return folders
175178
176179
177180def _get_allowed_read_folders (render_context : RenderContext ) -> list [str ]:
178181 """Return normalized absolute paths of folders the agent can read from.
179182
180- This is the write set, plus the module's memory folder, plus the whole
181- conformance-tests root . Agents may browse and read persisted memory notes (via
183+ This is the write set, plus the module's memory folder, plus every module's
184+ conformance-tests folder . Agents may browse and read persisted memory notes (via
182185 read_file/grep/ls_files) on demand, but may only add to them through the dedicated
183186 write_memory tool — so the memory folder is intentionally readable here while staying
184- out of the write set. The conformance-tests root is readable (read-only) so agents can
185- consult sibling modules' conformance tests as reference examples of how a conformance
187+ out of the write set. Sibling modules' conformance-tests folders are readable
188+ (read-only) so agents can consult them as reference examples of how a conformance
186189 test project for this project is laid out, built, and wired to run in isolation.
187190 """
188191 folders = list (_get_allowed_write_folders (render_context ))
189192 memory_manager = getattr (render_context , "memory_manager" , None )
190193 memory_folder = getattr (memory_manager , "memory_folder" , None ) if memory_manager else None
191194 if memory_folder :
192195 folders .append (os .path .normpath (os .path .abspath (memory_folder )))
193- conformance_root = getattr (render_context , "conformance_tests_folder" , None )
194- if conformance_root :
195- folders .append (os .path .normpath (os .path .abspath (conformance_root )))
196+ folders .extend (_get_all_module_tests_folders (render_context ))
196197 return folders
197198
198199
@@ -235,8 +236,7 @@ def build_sandbox_contract(render_context: RenderContext) -> str:
235236 if script
236237 ]
237238 modules_root = _get_modules_root (render_context )
238- conformance_root = getattr (render_context , "conformance_tests_folder" , None )
239- conformance_root = os .path .normpath (os .path .abspath (conformance_root )) if conformance_root else None
239+ sibling_tests_folders = _get_all_module_tests_folders (render_context )
240240
241241 lines = ["You can WRITE (create/edit/delete files) ONLY inside these folders:" ]
242242 lines .extend (f"- { folder } " for folder in write_folders )
@@ -249,9 +249,9 @@ def build_sandbox_contract(render_context: RenderContext) -> str:
249249 lines .append ("- The test/setup scripts (read-only harness files):" )
250250 lines .extend (f" - { script } " for script in scripts )
251251 lines .append ("- Temporary files under /tmp and /var/folders (e.g. saved test output)." )
252- if conformance_root :
252+ if sibling_tests_folders :
253253 lines .append (
254- f"- Every module's conformance tests under the conformance- tests root ( { conformance_root } ) "
254+ f"- Every module's conformance tests ( { os . path . join ( modules_root , '<module>' , ' tests' ) } ) "
255255 "(read-only). Sibling modules' conformance tests can be a good source of information — they "
256256 "already build and pass in this project's test harness. Explore them with ls_files/grep to "
257257 "find a relevant one rather than reading them all."
@@ -284,14 +284,27 @@ def build_sandbox_contract(render_context: RenderContext) -> str:
284284
285285
286286def _get_modules_root (render_context : RenderContext ) -> str :
287- """Return the directory that holds all per-module build folders.
287+ """Return the directory that holds all per-module folders.
288288
289- Build folders are constructed as ``<modules_root>/<module_name>`` (e.g.
290- ``plain_modules/module_2``), so the modules root is the build folder's parent. Its
291- other children are sibling module folders, which contain confusing near-duplicates
292- of the current build folder's code.
289+ Module folders are constructed as ``<modules_root>/<module_name>`` (e.g.
290+ ``plain_modules/module_2``), each holding the module's ``code/`` ( the build folder)
291+ and ``tests/`` trees. Sibling module folders contain confusing near-duplicates of
292+ the current build folder's code.
293293 """
294- return os .path .dirname (os .path .normpath (os .path .abspath (render_context .build_folder )))
294+ return os .path .normpath (os .path .abspath (render_context .plain_module .build_folder ))
295+
296+
297+ def _get_all_module_tests_folders (render_context : RenderContext ) -> list [str ]:
298+ """Return the existing conformance-tests folders of every module under the modules root."""
299+ modules_root = _get_modules_root (render_context )
300+ if not os .path .isdir (modules_root ):
301+ return []
302+ folders = []
303+ for module_name in sorted (os .listdir (modules_root )):
304+ tests_folder = render_context .conformance_tests .get_module_conformance_tests_folder (module_name )
305+ if os .path .isdir (tests_folder ):
306+ folders .append (os .path .normpath (os .path .abspath (tests_folder )))
307+ return folders
295308
296309
297310def _check_read_access (full_path : str , render_context : RenderContext ) -> str | None :
0 commit comments