Activate Taiga tracking only for infra ops work
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "taiga-auto-sync",
|
"name": "taiga-auto-sync",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0+codex.20260829130430",
|
||||||
"description": "Injects IT Infra & Ops Taiga tracking rules on every Claude prompt.",
|
"description": "Automatically tracks material IT Infra & Ops work and guards Taiga writes.",
|
||||||
"author": { "name": "Senkensha" },
|
"author": { "name": "Senkensha" },
|
||||||
"hooks": "./hooks/claude-codex-hooks.json"
|
"hooks": "./hooks/claude-codex-hooks.json"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,20 @@
|
|||||||
{
|
{
|
||||||
"name": "taiga-auto-sync",
|
"name": "taiga-auto-sync",
|
||||||
"version": "0.1.0+codex.20260829123342",
|
"version": "0.1.0+codex.20260829130430",
|
||||||
"description": "Injects mandatory sprint, owner, and tag guards on every Codex prompt.",
|
"description": "Automatically tracks material IT Infra & Ops work and guards Taiga writes.",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Local developer"
|
"name": "Local developer"
|
||||||
},
|
},
|
||||||
"hooks": "./hooks/claude-codex-hooks.json",
|
"hooks": "./hooks/claude-codex-hooks.json",
|
||||||
|
"skills": "./skills/",
|
||||||
"interface": {
|
"interface": {
|
||||||
"displayName": "Taiga Auto Sync",
|
"displayName": "Taiga Auto Sync",
|
||||||
"shortDescription": "Taiga governance guard.",
|
"shortDescription": "Automatic Infra/Ops Taiga tracking.",
|
||||||
"longDescription": "Guards active IT Infra & Ops work with a current sprint, owner, and required tags.",
|
"longDescription": "Tracks material IT Infra & Ops work by context and validates Taiga writes.",
|
||||||
"developerName": "Local developer",
|
"developerName": "Local developer",
|
||||||
"category": "Productivity",
|
"category": "Productivity",
|
||||||
"capabilities": [
|
"capabilities": [
|
||||||
|
"Skills",
|
||||||
"Lifecycle hooks"
|
"Lifecycle hooks"
|
||||||
],
|
],
|
||||||
"defaultPrompt": "Help me use Taiga Auto Sync."
|
"defaultPrompt": "Help me use Taiga Auto Sync."
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
{
|
{
|
||||||
"hooks": {
|
"hooks": {
|
||||||
"UserPromptSubmit": [{
|
"PreToolUse": [{
|
||||||
|
"matcher": "^mcp__taiga__(user_story|task|issue)_create$",
|
||||||
"hooks": [{
|
"hooks": [{
|
||||||
"type": "command",
|
"type": "command",
|
||||||
"command": "sh \"${CLAUDE_PLUGIN_ROOT}/hooks/taiga-reminder.sh\"",
|
"command": "python3 \"${CLAUDE_PLUGIN_ROOT}/hooks/taiga-write-guard.py\"",
|
||||||
"timeout": 3,
|
"timeout": 3,
|
||||||
"statusMessage": "Checking Taiga tracking..."
|
"statusMessage": "Checking Taiga item metadata..."
|
||||||
}]
|
}]
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
cat <<'EOF'
|
|
||||||
TAIGA AUTO-SYNC GUARD: For material IT Infra & Ops work, use Taiga before implementation; do not track read-only/no-op work.
|
|
||||||
|
|
||||||
Before creating or activating any User Story, Task, or Issue, resolve the sprint containing today in WIB. If none exists, create the Monday–Sunday `YYYY-WNN Operations` sprint first. Never leave an active item without its current sprint, an accountable owner, and one area, `source:<agent>`, and `system:<name>` or `repo:<name>` tag.
|
|
||||||
|
|
||||||
Classify one standalone daily activity as an Issue; use a User Story only for one outcome with two or more related Tasks, and create Tasks beneath that Story. A new User Story must use the Wiki description template. Use the corresponding Wiki template for Task or Issue descriptions. Preserve per-item local state for progress, blocked, and verified done updates; do not put secrets in it.
|
|
||||||
EOF
|
|
||||||
58
plugins/taiga-auto-sync/hooks/taiga-write-guard.py
Normal file
58
plugins/taiga-auto-sync/hooks/taiga-write-guard.py
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
#!/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()
|
||||||
15
plugins/taiga-auto-sync/skills/taiga-operations/SKILL.md
Normal file
15
plugins/taiga-auto-sync/skills/taiga-operations/SKILL.md
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
name: taiga-operations
|
||||||
|
description: Automatically track material IT Infrastructure & Operations implementation in Taiga, including deploys, incidents, maintenance, access, backup, monitoring, and infrastructure changes. Do not use for read-only questions, exploration, status explanations, or unrelated product work.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Taiga Operations
|
||||||
|
|
||||||
|
Use this workflow automatically when the prompt requests material IT Infra & Ops work. The user does not need to ask for a Taiga update.
|
||||||
|
|
||||||
|
1. Do not create or update Taiga for reading, investigation without a change, planning only, no-op work, or secrets.
|
||||||
|
2. Before creating or activating an item, find the sprint that covers today in WIB. If none exists, create the Monday–Sunday `YYYY-WNN Operations` sprint, then use it.
|
||||||
|
3. Find an existing matching open item before creating a new one. Reuse its local state reference when available.
|
||||||
|
4. Classify a standalone daily operation as an Issue. Use one User Story only for one outcome with two or more related Tasks; create those Tasks beneath it.
|
||||||
|
5. Every active User Story, Task, and Issue needs an owner, current sprint, one area tag, one `source:<agent>` tag, and one `repo:<name>` or `system:<name>` tag.
|
||||||
|
6. Use the Wiki template for the selected item type. Record only material `start`, `progress`, `blocked`, and verified `done` events. Never put credentials or sensitive evidence in Taiga or local state.
|
||||||
Reference in New Issue
Block a user