Merge pull request #1167 from arnoldwender/fix/kg-date-validation
fix(kg): validate ISO-8601 date formats at MCP boundary
This commit is contained in:
@@ -788,6 +788,59 @@ class TestKGTools:
|
||||
result = tool_kg_stats()
|
||||
assert result["entities"] >= 4
|
||||
|
||||
# --- Date validation at the MCP boundary (issue #1164) ---
|
||||
|
||||
def test_kg_add_rejects_invalid_valid_from(self, monkeypatch, config, palace_path, kg):
|
||||
_patch_mcp_server(monkeypatch, config, kg)
|
||||
from mempalace.mcp_server import tool_kg_add
|
||||
|
||||
result = tool_kg_add(
|
||||
subject="Alice",
|
||||
predicate="likes",
|
||||
object="coffee",
|
||||
valid_from="Jan 2025",
|
||||
)
|
||||
assert result["success"] is False
|
||||
assert "valid_from" in result["error"]
|
||||
assert "ISO-8601" in result["error"]
|
||||
|
||||
def test_kg_query_rejects_invalid_as_of(self, monkeypatch, config, palace_path, seeded_kg):
|
||||
_patch_mcp_server(monkeypatch, config, seeded_kg)
|
||||
from mempalace.mcp_server import tool_kg_query
|
||||
|
||||
result = tool_kg_query(entity="Max", as_of="March 2026")
|
||||
assert "error" in result
|
||||
assert "as_of" in result["error"]
|
||||
|
||||
def test_kg_invalidate_rejects_invalid_ended(self, monkeypatch, config, palace_path, seeded_kg):
|
||||
_patch_mcp_server(monkeypatch, config, seeded_kg)
|
||||
from mempalace.mcp_server import tool_kg_invalidate
|
||||
|
||||
result = tool_kg_invalidate(
|
||||
subject="Max",
|
||||
predicate="does",
|
||||
object="chess",
|
||||
ended="yesterday",
|
||||
)
|
||||
assert result["success"] is False
|
||||
assert "ended" in result["error"]
|
||||
|
||||
def test_kg_query_rejects_partial_iso_dates(self, monkeypatch, config, palace_path, seeded_kg):
|
||||
_patch_mcp_server(monkeypatch, config, seeded_kg)
|
||||
from mempalace.mcp_server import tool_kg_query
|
||||
|
||||
# Partial ISO dates are rejected: KG queries compare TEXT dates
|
||||
# lexicographically, so "2026-01-01" <= "2026" is False, which
|
||||
# silently excludes facts. Reject at the boundary — only YYYY-MM-DD
|
||||
# produces correct results.
|
||||
for value in ("2026", "2026-03"):
|
||||
result = tool_kg_query(entity="Max", as_of=value)
|
||||
assert "error" in result, f"accepted partial date {value!r}: {result}"
|
||||
|
||||
# Full ISO-8601 dates still pass.
|
||||
result = tool_kg_query(entity="Max", as_of="2026-03-15")
|
||||
assert "error" not in result, f"rejected valid date: {result}"
|
||||
|
||||
|
||||
# ── Diary Tools ─────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
Reference in New Issue
Block a user