mirror of
https://github.com/github/spec-kit.git
synced 2026-08-03 06:26:30 +08:00
fix(bundler): reject non-mapping 'integration' in a bundle manifest (#3629)
BundleManifest.from_dict guarded 'requires' and 'provides' with "must be a mapping when present", but a present-but-non-mapping 'integration' (e.g. a bare string "copilot") silently failed the isinstance(dict) check and was dropped — leaving the bundle wrongly integration-agnostic (is_agnostic() True) instead of surfacing the authoring mistake. Add the same guard so 'integration' is consistent with its sibling mapping fields. Test: integration='copilot' now raises BundlerError (fails before: silently dropped, no raise). Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -122,6 +122,11 @@ class BundleManifest:
|
||||
|
||||
integration = None
|
||||
integration_raw = data.get("integration")
|
||||
# Mirror the requires/provides guards above: a present-but-non-mapping
|
||||
# 'integration' (e.g. a bare string "copilot") was silently dropped,
|
||||
# leaving the bundle wrongly integration-agnostic. Reject it instead.
|
||||
if integration_raw is not None and not isinstance(integration_raw, dict):
|
||||
raise BundlerError("'integration' must be a mapping when present.")
|
||||
if isinstance(integration_raw, dict) and integration_raw.get("id"):
|
||||
integration = IntegrationRef(id=str(integration_raw["id"]).strip())
|
||||
|
||||
|
||||
@@ -124,3 +124,13 @@ def test_string_mcp_rejected_not_split_per_character():
|
||||
data["requires"]["mcp"] = "github"
|
||||
with pytest.raises(BundlerError, match="'requires.mcp' must be a list of strings"):
|
||||
BundleManifest.from_dict(data)
|
||||
|
||||
|
||||
def test_string_integration_rejected_not_silently_dropped():
|
||||
# A present-but-non-mapping 'integration' (a bare string) was silently
|
||||
# dropped, leaving the bundle wrongly integration-agnostic. Reject it like
|
||||
# the sibling requires/provides mapping fields.
|
||||
data = valid_manifest_dict()
|
||||
data["integration"] = "copilot"
|
||||
with pytest.raises(BundlerError, match="'integration' must be a mapping when present"):
|
||||
BundleManifest.from_dict(data)
|
||||
|
||||
Reference in New Issue
Block a user