$npx -y skills add stellarlinkco/skills --skill harnessThis skill should be used for multi-session autonomous agent work requiring progress checkpointing, failure recovery, and task dependency management. Triggers on '/harness' command, or when a task involves many subtasks needing progress persistence, sleep/resume cycles across con
| 1 | # Harness — Long-Running Agent Framework |
| 2 | |
| 3 | Executable protocol enabling any agent task to run continuously across multiple sessions with automatic progress recovery, task dependency resolution, failure rollback, and standardized error handling. |
| 4 | |
| 5 | ## Design Principles |
| 6 | |
| 7 | 1. **Design for the agent, not the human** — Test output, docs, and task structure are the agent's primary interface |
| 8 | 2. **Progress files ARE the context** — When context window resets, progress files + git history = full recovery |
| 9 | 3. **Premature completion is the #1 failure mode** — Structured task lists with explicit completion criteria prevent declaring victory early |
| 10 | 4. **Standardize everything grep-able** — ERROR on same line, structured timestamps, consistent prefixes |
| 11 | 5. **Fast feedback loops** — Pre-compute stats, run smoke tests before full validation |
| 12 | 6. **Idempotent everything** — Init scripts, task execution, environment setup must all be safe to re-run |
| 13 | 7. **Fail safe, not fail silent** — Every failure must have an explicit recovery strategy |
| 14 | |
| 15 | ## Commands |
| 16 | |
| 17 | ``` |
| 18 | /harness init <project-path> # Initialize harness files in project |
| 19 | /harness run # Start/resume the infinite loop |
| 20 | /harness status # Show current progress and stats |
| 21 | /harness add "task description" # Add a task to the list |
| 22 | ``` |
| 23 | |
| 24 | ## Activation Marker |
| 25 | |
| 26 | Hooks only take effect when `.harness-active` marker file exists in the harness root (same directory as `harness-tasks.json`). |
| 27 | |
| 28 | - `/harness init` and `/harness run` MUST create this marker: `touch <project-path>/.harness-active` |
| 29 | - When all tasks complete (no pending/in_progress/retryable left), remove it: `rm <project-path>/.harness-active` |
| 30 | - Without this marker, all hooks are no-ops — they exit 0 immediately |
| 31 | |
| 32 | ## Progress Persistence (Dual-File System) |
| 33 | |
| 34 | Maintain two files in the project working directory: |
| 35 | |
| 36 | ### harness-progress.txt (Append-Only Log) |
| 37 | |
| 38 | Free-text log of all agent actions across sessions. Never truncate. |
| 39 | |
| 40 | ``` |
| 41 | [2025-07-01T10:00:00Z] [SESSION-1] INIT Harness initialized for project /path/to/project |
| 42 | [2025-07-01T10:00:05Z] [SESSION-1] INIT Environment health check: PASS |
| 43 | [2025-07-01T10:00:10Z] [SESSION-1] LOCK acquired (pid=12345) |
| 44 | [2025-07-01T10:00:11Z] [SESSION-1] Starting [task-001] Implement user authentication (base=def5678) |
| 45 | [2025-07-01T10:05:00Z] [SESSION-1] CHECKPOINT [task-001] step=2/4 "auth routes created, tests pending" |
| 46 | [2025-07-01T10:15:30Z] [SESSION-1] Completed [task-001] (commit abc1234) |
| 47 | [2025-07-01T10:15:31Z] [SESSION-1] Starting [task-002] Add rate limiting (base=abc1234) |
| 48 | [2025-07-01T10:20:00Z] [SESSION-1] ERROR [task-002] [TASK_EXEC] Redis connection refused |
| 49 | [2025-07-01T10:20:01Z] [SESSION-1] ROLLBACK [task-002] git reset --hard abc1234 |
| 50 | [2025-07-01T10:20:02Z] [SESSION-1] STATS tasks_total=5 completed=1 failed=1 pending=3 blocked=0 attempts_total=2 checkpoints=1 |
| 51 | ``` |
| 52 | |
| 53 | ### harness-tasks.json (Structured State) |
| 54 | |
| 55 | ```json |
| 56 | { |
| 57 | "version": 2, |
| 58 | "created": "2025-07-01T10:00:00Z", |
| 59 | "session_config": { |
| 60 | "concurrency_mode": "exclusive", |
| 61 | "max_tasks_per_session": 20, |
| 62 | "max_sessions": 50 |
| 63 | }, |
| 64 | "tasks": [ |
| 65 | { |
| 66 | "id": "task-001", |
| 67 | "title": "Implement user authentication", |
| 68 | "status": "completed", |
| 69 | "priority": "P0", |
| 70 | "depends_on": [], |
| 71 | "attempts": 1, |
| 72 | "max_attempts": 3, |
| 73 | "started_at_commit": "def5678", |
| 74 | "validation": { |
| 75 | "command": "npm test -- --testPathPattern=auth", |
| 76 | "timeout_seconds": 300 |
| 77 | }, |
| 78 | "on_failure": { |
| 79 | "cleanup": null |
| 80 | }, |
| 81 | "error_log": [], |
| 82 | "checkpoints": [], |
| 83 | "completed_at": "2025-07-01T10:15:30Z" |
| 84 | }, |
| 85 | { |
| 86 | "id": "task-002", |
| 87 | "title": "Add rate limiting", |
| 88 | "status": "failed", |
| 89 | "priority": "P1", |
| 90 | "depends_on": [], |
| 91 | "attempts": 1, |
| 92 | "max_attempts": 3, |
| 93 | "started_at_commit": "abc1234", |
| 94 | "validation": { |
| 95 | "command": "npm test -- --testPathPattern=rate-limit", |
| 96 | "timeout_seconds": 120 |
| 97 | }, |
| 98 | "on_failure": { |
| 99 | "cleanup": "docker compose down redis" |
| 100 | }, |
| 101 | "error_log": ["[TASK_EXEC] Redis connection refused"], |
| 102 | "checkpoints": [], |
| 103 | "completed_at": null |
| 104 | }, |
| 105 | { |
| 106 | "id": "task-003", |
| 107 | "title": "Add OAuth providers", |
| 108 | "status": "pending", |
| 109 | "priority": "P1", |
| 110 | "depends_on": ["task-001"], |
| 111 | "attempts": 0, |
| 112 | "max_attempts": 3, |
| 113 | "started_at_commit": null, |
| 114 | "validation": { |
| 115 | "command": "npm test -- --testPathPattern=oauth", |