@@ -263,9 +263,15 @@ def test_scaffold_command_file_count(agent, scaffolded_sh, source_template_stems
263263
264264 cmd_dir = _expected_cmd_dir (project , agent )
265265 generated = _list_command_files (cmd_dir , agent )
266+
267+ if cmd_dir .is_dir ():
268+ dir_listing = list (cmd_dir .iterdir ())
269+ else :
270+ dir_listing = f"<command dir missing: { cmd_dir } >"
271+
266272 assert len (generated ) == len (source_template_stems ), (
267273 f"Agent '{ agent } ': expected { len (source_template_stems )} command files "
268- f"({ _expected_ext (agent )} ), found { len (generated )} . Dir: { list ( cmd_dir . iterdir ()) } "
274+ f"({ _expected_ext (agent )} ), found { len (generated )} . Dir: { dir_listing } "
269275 )
270276
271277
@@ -493,39 +499,53 @@ def test_scaffold_powershell_variant(agent, scaffolded_ps, source_template_stems
493499# 8. Parity: bundled vs. real create-release-packages.sh ZIP
494500# ---------------------------------------------------------------------------
495501
502+ @pytest .fixture (scope = "session" )
503+ def release_script_trees (tmp_path_factory ):
504+ """Session-scoped cache: run release script once per (agent, script_type)."""
505+ cache : dict [tuple [str , str ], dict [str , bytes ]] = {}
506+ bash = _find_bash ()
507+
508+ def _get (agent : str , script_type : str ) -> dict [str , bytes ] | None :
509+ if bash is None :
510+ return None
511+ key = (agent , script_type )
512+ if key not in cache :
513+ tmp = tmp_path_factory .mktemp (f"release_{ agent } _{ script_type } " )
514+ gen_dir = tmp / "genreleases"
515+ gen_dir .mkdir ()
516+ zip_path = _run_release_script (agent , script_type , bash , gen_dir )
517+ extracted = tmp / "extracted"
518+ extracted .mkdir ()
519+ with zipfile .ZipFile (zip_path ) as zf :
520+ zf .extractall (extracted )
521+ cache [key ] = _collect_relative_files (extracted )
522+ return cache [key ]
523+ return _get
524+
525+
496526@pytest .mark .parametrize ("script_type" , ["sh" , "ps" ])
497527@pytest .mark .parametrize ("agent" , _TESTABLE_AGENTS )
498- def test_parity_bundled_vs_release_script (tmp_path , agent , script_type ):
528+ def test_parity_bundled_vs_release_script (agent , script_type , scaffolded_sh , scaffolded_ps , release_script_trees ):
499529 """scaffold_from_core_pack() file tree is identical to the ZIP produced by
500530 create-release-packages.sh for every agent and script type.
501531
502532 This is the true end-to-end parity check: the Python offline path must
503533 produce exactly the same artifacts as the canonical shell release script.
504534
505- Each agent is tested independently: generate the release ZIP, generate
506- the bundled scaffold, compare. This avoids cross-agent interference
507- from the release script's rm -rf at startup.
535+ Both sides are session-cached: each agent/script_type combination is
536+ scaffolded and release-scripted only once across all tests.
508537 """
509- bash = _find_bash ( )
510- if bash is None :
538+ script_tree = release_script_trees ( agent , script_type )
539+ if script_tree is None :
511540 pytest .skip ("bash required to run create-release-packages.sh" )
512541
513- # --- Release script path ---
514- gen_dir = tmp_path / "genreleases"
515- gen_dir .mkdir ()
516- zip_path = _run_release_script (agent , script_type , bash , gen_dir )
517- script_dir = tmp_path / "extracted"
518- script_dir .mkdir ()
519- with zipfile .ZipFile (zip_path ) as zf :
520- zf .extractall (script_dir )
521-
522- # --- Bundled path ---
523- bundled_dir = tmp_path / "bundled"
524- ok = scaffold_from_core_pack (bundled_dir , agent , script_type )
525- assert ok
542+ # Reuse session-cached scaffold output
543+ if script_type == "sh" :
544+ bundled_dir = scaffolded_sh (agent )
545+ else :
546+ bundled_dir = scaffolded_ps (agent )
526547
527548 bundled_tree = _collect_relative_files (bundled_dir )
528- script_tree = _collect_relative_files (script_dir )
529549
530550 only_bundled = set (bundled_tree ) - set (script_tree )
531551 only_script = set (script_tree ) - set (bundled_tree )
0 commit comments