59 lines
1.7 KiB
Python
59 lines
1.7 KiB
Python
#!/usr/bin/env python3
|
|
"""Reject Taiga item creation without the active-item metadata contract."""
|
|
import json
|
|
import sys
|
|
|
|
AREAS = {
|
|
"infra", "network", "cloud", "security", "backup", "monitoring",
|
|
"access", "automation", "support", "vendor",
|
|
}
|
|
|
|
|
|
def missing_fields(payload):
|
|
item = payload.get("tool_input", {})
|
|
tags = set(item.get("tags") or [])
|
|
missing = []
|
|
if not item.get("assigned_to"):
|
|
missing.append("owner")
|
|
if not item.get("milestone"):
|
|
missing.append("current sprint")
|
|
if not tags.intersection(AREAS):
|
|
missing.append("area tag")
|
|
if not any(tag.startswith("source:") for tag in tags):
|
|
missing.append("source tag")
|
|
if not any(tag.startswith(("repo:", "system:")) for tag in tags):
|
|
missing.append("target tag")
|
|
return missing
|
|
|
|
|
|
def result(payload):
|
|
missing = missing_fields(payload)
|
|
if not missing:
|
|
return None
|
|
return {
|
|
"hookSpecificOutput": {
|
|
"hookEventName": "PreToolUse",
|
|
"permissionDecision": "deny",
|
|
"permissionDecisionReason": (
|
|
"Taiga item creation requires " + ", ".join(missing) +
|
|
". Resolve or create the current WIB sprint first."
|
|
),
|
|
}
|
|
}
|
|
|
|
|
|
def main():
|
|
if sys.argv[1:] == ["--self-check"]:
|
|
assert result({"tool_input": {"assigned_to": 1, "milestone": 1,
|
|
"tags": ["infra", "source:codex", "repo:brain"]}}) is None
|
|
assert result({"tool_input": {"tags": []}})
|
|
print("self-check: ok")
|
|
return
|
|
output = result(json.load(sys.stdin))
|
|
if output:
|
|
print(json.dumps(output))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|