Workflow Guard Skill
This skill turns workflow rules into hard gates for Claude Code file edits.
Core model:
- Skill = SOP definition.
- Hook = enforcement.
- Marker file (
.workflow-active) = session state.
Included Files
workflow-guard-skill/
SKILL.md
scripts/
workflow_common.py
workflow_activate.py
workflow_session_check.py
workflow_gate.py
Behavior
workflow_gate.py guards Edit|Write|MultiEdit|NotebookEdit when:
- project is workflow-managed (
PROJECT.mdexists), and - marker state is checked before edit.
Default mode is auto-activation:
- missing/stale/invalid
.workflow-activeis created/refreshed automatically. - strict blocking can be restored with
--no-auto-activate.
Default TTL is 4 hours.
Bootstrap exemptions are built in for:
.claude/hooks/workflow-gate.py.claude/hooks/workflow-session-check.py.claude/hooks/workflow-activate.py
Install
Copy this folder to:
~/.claude/skills/workflow-guard/Add project marker in each managed repo:
PROJECT.mdRegister hook in
~/.claude/settings.jsonor.claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write|MultiEdit|NotebookEdit",
"hooks": [
{
"type": "command",
"command": "python3 \"$HOME/.claude/skills/workflow-guard/scripts/workflow-gate.py\" --auto-activate --ttl-hours 4"
}
]
}
]
}
}
You can also add a second check hook if needed:
{
"type": "command",
"command": "python3 \"$HOME/.claude/skills/workflow-guard/scripts/workflow-session-check.py\""
}
Daily Use
In auto-activation mode, no manual command is required.
Optional manual activation is still available:
python3 "$HOME/.claude/skills/workflow-guard/scripts/workflow-activate.py" --project-root "$PWD" --ttl-hours 4
If you prefer strict mode, set hook command to:
python3 "$HOME/.claude/skills/workflow-guard/scripts/workflow-gate.py" --no-auto-activate
Quick Validation
- Ensure repo contains
PROJECT.md. - Ask Claude to edit a file.
- Confirm
.workflow-activeis auto-created. - For strict mode testing, use
--no-auto-activateand verify block behavior.
Notes
- Blocking uses
exit 2and stderr feedback. - Hook input is read from stdin JSON (
tool_name,tool_input,cwd). - Scripts force UTF-8 stdout/stderr for cross-platform stability.