From 38bb42c288debfe5445d108483502936732d96e6 Mon Sep 17 00:00:00 2001 From: huangruiteng <14976749+huangruiteng@users.noreply.github.com> Date: Wed, 16 Sep 2026 21:59:52 +0800 Subject: [PATCH] test(install): expect the fixed install to keep repo-only skills in the checkout The fixed installer classifies skill sources in the capability that owns the scope marker and delivers only declared global scopes, so a repo-kept workflow with no `.loopx-skill-scope` never reaches a host. This smoke still expected the source install to materialize `loopx-pr-merge`, which is why it fails on main. Assert the delivered set is the entry plus the declared global skills, and make the repo-only omission explicit the way the promotion-boundary smoke already does, so a re-introduced delivery fails here instead of shipping a merge-decision workflow to hosts that never merge LoopX pull requests. Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com> --- examples/install-local-smoke.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/examples/install-local-smoke.py b/examples/install-local-smoke.py index ad2f836533..387296e5cd 100644 --- a/examples/install-local-smoke.py +++ b/examples/install-local-smoke.py @@ -364,11 +364,23 @@ def main() -> int: ) assert skill_readback["integration_mode"] == "fixed_install_script" assert skill_readback["source"]["revision"] == source_commit - assert set(skill_readback["materialized_skill_ids"]) == { + materialized_skill_ids = set(skill_readback["materialized_skill_ids"]) + assert materialized_skill_ids == { "loopx", - "loopx-pr-merge", # Source installer also ships the merge workflow. *PACKAGED_HOST_SKILL_IDS, } + # Only declared global scopes are delivered: a repo-kept workflow carries + # no scope marker, so the fixed install keeps it in the checkout instead + # of copying a merge-decision workflow onto a host that never merges. + repo_only_skill_ids = { + path.name + for path in (REPO_ROOT / "skills").iterdir() + if path.is_dir() and not (path / ".loopx-skill-scope").exists() + } + assert repo_only_skill_ids, "the checkout no longer carries a repo-only skill source" + assert not (materialized_skill_ids & repo_only_skill_ids), sorted( + materialized_skill_ids & repo_only_skill_ids + ) skill_text = skill.read_text(encoding="utf-8") compact_skill_text = " ".join(skill_text.split()) for phrase in (