Skip to content
Open
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
34 changes: 34 additions & 0 deletions scripts/test/test-T001-workflow-spec.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/usr/bin/env bash
# Test: spec and workflow YAML exist for 005-add-workflows-to-hookrunner
set -euo pipefail
cd "$(dirname "$0")/../.."

errors=0

# Spec exists
if [ -f "specs/005-add-workflows-to-hookrunner/spec.md" ]; then
echo "[OK] spec.md exists"
else
echo "[FAIL] specs/005-add-workflows-to-hookrunner/spec.md missing"
errors=$((errors + 1))
fi

# Spec has required sections
for section in "Problem" "Solution" "Architecture"; do
if grep -qi "$section" specs/005-add-workflows-to-hookrunner/spec.md 2>/dev/null; then
echo "[OK] spec has $section section"
else
echo "[FAIL] spec missing $section section"
errors=$((errors + 1))
fi
done

# Workflow YAML exists
if [ -f "workflows/005-add-workflows-to-hookrunner.yml" ]; then
echo "[OK] workflow YAML exists"
else
echo "[FAIL] workflows/005-add-workflows-to-hookrunner.yml missing"
errors=$((errors + 1))
fi

exit $errors
74 changes: 74 additions & 0 deletions specs/005-add-workflows-to-hookrunner/spec.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# 005: Add Workflows to Hook-Runner

## Problem

Spec-hook has a workflow engine (YAML step pipelines with gate enforcement) that only works within SHTD flow. The engine should be a hook-runner feature so any project can define workflows without depending on spec-hook. Currently:

- Workflow engine lives in `spec-hook/lib/workflow.js` — wrong home
- Workflow gate is an SHTD module — should be a hook-runner module
- No CLI integration in hook-runner (`--workflow` commands)
- No way to enforce "always use workflows" without manual discipline
- Cross-project context reset behavior needs workflow enforcement

## Solution

Move the workflow engine to hook-runner as a first-class feature:

1. **workflow.js** → hook-runner lib (zero-dep YAML parser + state machine)
2. **workflow-gate module** → hook-runner PreToolUse catalog
3. **CLI commands** → `node setup.js --workflow list|start|status|complete|reset`
4. **Global workflows** → `~/.claude/hooks/workflows/` (shared across projects)
5. **Project workflows** → `workflows/` in project root (project-specific)
6. **Meta-workflow** → `enforce-shtd.yml` that enforces SHTD pipeline using itself

## Architecture

```
hook-runner/
workflow.js # Engine: YAML parser, state machine, gate checker
modules/PreToolUse/
workflow-gate.js # Gate: blocks out-of-order edits per active workflow
workflows/ # Built-in workflow templates
enforce-shtd.yml # Meta: enforce spec→test→branch→PR pipeline
cross-project-reset.yml # Context reset when switching projects
```

### Workflow Discovery (priority order)
1. Project: `$CLAUDE_PROJECT_DIR/workflows/*.yml`
2. Global: `~/.claude/hooks/workflows/*.yml`
3. Built-in: hook-runner `workflows/` directory

### State
- Per-project: `$CLAUDE_PROJECT_DIR/.workflow-state.json`
- Tracks: active workflow name, step statuses, timestamps

### Gate Logic
- On Write/Edit: check if active workflow exists → validate current step's gate
- Gates: `require_step` (previous step completed), `require_files` (files exist)
- Allowed paths bypass gates (TODO.md, CLAUDE.md, specs/, tests/, etc.)

## Cross-Project Context Reset Workflow

When TODO.md is complete and a new project is requested:
1. Save state to current project's TODO.md
2. Commit and push current project
3. Create TODO.md in new project (if needed)
4. Context reset into new project directory
5. Variables control behavior:
- `PRESERVE_TAB=true` — keep old project tab open
- `CONTINUE_BOTH=true` — work in both projects (no stop)
- Default: stop old, start new

## Enforce-SHTD Meta-Workflow

A workflow that enforces "always use workflows when making behavioral rules":
1. Any new behavioral rule must start with a workflow YAML
2. The workflow defines enforcement steps
3. Only after workflow is active can gates/modules be created
4. Self-referential: this workflow enforces its own creation pattern

## Scope

- hook-runner gets: workflow.js, workflow-gate module, CLI commands, built-in templates
- spec-hook gets: updated to delegate to hook-runner's engine (thin wrapper)
- Both projects get PRs
25 changes: 25 additions & 0 deletions specs/005-add-workflows-to-hookrunner/tasks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Tasks: 005 — Add Workflows to Hook-Runner

## Phase 1: Spec & Plan (spec-hook)
- [x] T001 Write spec, workflow YAML, and tasks for this feature
**Checkpoint**: `bash scripts/test/test-T001-workflow-spec.sh`

## Phase 2: Build in hook-runner
- [ ] T002 Port workflow.js to hook-runner (extract from spec-hook, zero deps)
**Checkpoint**: `bash scripts/test/test-T002-hookrunner-engine.sh`
- [ ] T003 Add workflow-gate PreToolUse module to hook-runner catalog
**Checkpoint**: `bash scripts/test/test-T003-hookrunner-gate.sh`
- [ ] T004 Add --workflow CLI commands to setup.js (list, start, status, complete, reset)
**Checkpoint**: `bash scripts/test/test-T004-hookrunner-cli.sh`
- [ ] T005 Add built-in workflow templates (enforce-shtd.yml, cross-project-reset.yml)
**Checkpoint**: `bash scripts/test/test-T005-workflow-templates.sh`
- [ ] T006 Tests for workflow engine + gate + CLI
**Checkpoint**: `bash scripts/test/test-T006-hookrunner-e2e.sh`

## Phase 3: Meta-workflow & SHTD update
- [ ] T007 Create enforce-shtd.yml meta-workflow (enforces using SHTD to create rules)
**Checkpoint**: `bash scripts/test/test-T007-enforce-shtd.sh`
- [ ] T008 Update spec-hook to delegate to hook-runner's workflow engine
**Checkpoint**: `bash scripts/test/test-T008-shtd-delegation.sh`
- [ ] T009 PR for hook-runner, PR for spec-hook, update docs
**Checkpoint**: `bash scripts/test/test-T009-final-verify.sh`
58 changes: 58 additions & 0 deletions workflows/005-add-workflows-to-hookrunner.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: add-workflows-to-hookrunner
description: Move workflow engine from spec-hook to hook-runner as a first-class feature
version: 1
steps:
- id: spec
name: Write spec for hook-runner workflow feature
gate:
require_files: []
completion:
require_files: ["specs/005-add-workflows-to-hookrunner/spec.md"]
- id: tasks
name: Break spec into tasks
gate:
require_step: spec
completion:
require_files: ["specs/005-add-workflows-to-hookrunner/tasks.md"]
- id: engine
name: Port workflow engine to hook-runner
gate:
require_step: tasks
completion:
require_files: []
- id: gate-module
name: Add workflow-gate PreToolUse module to hook-runner
gate:
require_step: engine
completion:
require_files: []
- id: cli
name: Add workflow CLI commands to hook-runner setup.js
gate:
require_step: gate-module
completion:
require_files: []
- id: templates
name: Add built-in workflow templates
gate:
require_step: cli
completion:
require_files: []
- id: test
name: Test workflow engine end-to-end
gate:
require_step: templates
completion:
require_files: []
- id: meta-workflow
name: Create enforce-shtd meta-workflow
gate:
require_step: test
completion:
require_files: []
- id: update-shtd
name: Update spec-hook to delegate to hook-runner engine
gate:
require_step: meta-workflow
completion:
require_files: []