Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/talonctl/schemas/envelope.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
25 changes: 25 additions & 0 deletions tests/unit/test_envelope_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Loading