diff --git a/CHANGELOG.md b/CHANGELOG.md index 32ce78c..deacaad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,21 @@ ## [Unreleased] +## v0.5.9 — hotfix: accept case management kinds in schema validator + +### Fixed + +- **`talonctl validate` now accepts `CaseNotificationGroup`, `CaseSla`, and + `CaseTemplate` envelopes.** The JSON Schema enum in + `schemas/envelope.schema.json` was never updated when the three case kinds + were added to `KIND_TO_TYPE`, causing `validate_authored_envelope()` to + reject all case management templates with an "is not one of" error. The + Python code (provider registry, template discovery, `VALID_KINDS`) was + correct; only the JSON Schema enum was stale. +- **Drift-guard test added** (`test_schema_kind_enum_matches_kind_to_type`) + that asserts the schema's kind enum exactly matches `KIND_TO_TYPE.keys()`, + so the two sources of truth cannot diverge again. + ## v0.5.8 — case management resources (notification groups, SLAs, templates) ### Added diff --git a/src/talonctl/schemas/envelope.schema.json b/src/talonctl/schemas/envelope.schema.json index c857383..2b80991 100644 --- a/src/talonctl/schemas/envelope.schema.json +++ b/src/talonctl/schemas/envelope.schema.json @@ -9,7 +9,7 @@ "apiVersion": { "const": "talon/v2" }, "kind": { "type": "string", - "enum": ["Detection", "SavedSearch", "LookupFile", "Workflow", "Dashboard", "RtrScript", "RtrPutFile"] + "enum": ["Detection", "SavedSearch", "LookupFile", "Workflow", "Dashboard", "RtrScript", "RtrPutFile", "CaseNotificationGroup", "CaseSla", "CaseTemplate"] }, "metadata": { "type": "object", diff --git a/tests/unit/test_envelope_validation.py b/tests/unit/test_envelope_validation.py index 923384c..1e516de 100644 --- a/tests/unit/test_envelope_validation.py +++ b/tests/unit/test_envelope_validation.py @@ -87,3 +87,28 @@ def test_whitespace_hygiene_checks_metadata_and_nested(): env = Envelope("talon/v2", "Dashboard", {"resource_id": "d"}, {"widgets": {"w1": {"queryString": "#a\n| b \n"}}}) errs = check_whitespace_hygiene(env) assert any("trailing whitespace" in e and "widgets.w1.queryString" in e for e in errs) + + +def test_validate_authored_envelope_accepts_case_kinds(): + """Schema kind enum must include all three case management kinds.""" + for kind in ("CaseNotificationGroup", "CaseSla", "CaseTemplate"): + env = Envelope( + "talon/v2", + kind, + {"resource_id": "test_resource", "name": "Test"}, + {"name": "Test"}, + ) + errors = validate_authored_envelope(env) + assert errors == [], f"{kind} rejected by schema: {errors}" + + +def test_schema_kind_enum_matches_kind_to_type(): + """Schema kind enum must stay in sync with KIND_TO_TYPE (drift guard).""" + import json + from importlib import resources as importlib_resources + from talonctl.core.envelope import KIND_TO_TYPE + + text = importlib_resources.files("talonctl.schemas").joinpath("envelope.schema.json").read_text() + schema = json.loads(text) + schema_kinds = set(schema["properties"]["kind"]["enum"]) + assert schema_kinds == set(KIND_TO_TYPE.keys())