Orients to a harness-managed project state, verifies git identity and smoke test, chooses single-session or Agent Teams mode, and guides TDD implementation with quality gates.
How this skill is triggered — by the user, by Claude, or both
Slash command
/vv-harness:harness-continueThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
The vv-harness plugin's SessionStart hook auto-injects orientation at session start:
The vv-harness plugin's SessionStart hook auto-injects orientation at session start: feature summary, next claimable feature, last handoff, Active Context, a git identity warning on mismatch, and any SESSION_INCOMPLETE gaps from the previous session. Use that injected "## Harness orientation" block instead of re-reading the harness files. Resolve any SESSION_INCOMPLETE gaps it surfaces before starting new work.
This skill covers what the hook does not: mode choice, the smoke test, and team planning.
Check for untracked files and inherited task quality:
git status -s # surface unknown untracked files
If you see untracked files you didn't create (e.g., notes.md, scratch files), surface them to the user immediately: "I see [file] untracked — should I delete it, gitignore it, or leave it?" This takes 5 seconds and prevents orphaned file accumulation.
If inheriting tasks from a previous session, verify they have required metadata fields (feature_id at minimum) via TaskList. Tasks without feature_id can't be correlated by hooks or retrospectives. Update them with TaskUpdate now if they're missing it.
The SessionStart hook already compared git config user.email against
.harness/harness.json and warned on mismatch (non-blocking). If the orientation
block shows an identity warning, fix it before proceeding. Also verify the SSH
identity, which the hook does not check:
ssh -T [email protected] 2>&1 || true
Do not skip this.
Run the project's build/test smoke test:
./.harness/init.sh
This is a gate, not a diagnostic. Its purpose is to confirm the environment is in a known-good state BEFORE any changes. If it fails, you know the problem is pre-existing, not something you introduced. Run it within the first 5 actions of every session. No exceptions. The 15-second cost prevents 15-minute debugging sessions later.
Set effort based on the current phase:
/effort high/effort medium (default)/effort lowAdjust as you transition between phases during the session.
Choose Single-Session if:
harness.json team_structure is nullWhen choosing single-session, explicitly declare it: "Running in single-session mode — I'm both lead and implementer." This makes the decision conscious and documented, preventing ambiguity between "I forgot plan mode" and "plan mode doesn't apply here."
Choose Agent Teams if:
harness.json has a team_structure definedGraceful degradation — Agent Teams unavailable:
Agent Teams is gated by CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1; the implicit team,
SendMessage, and the TaskCompleted/TeammateIdle coordination hooks are active only
when it is set. If the variable is unset or team coordination is unavailable, do NOT
abort parallel work. Fall back to direct subagents spawned via the Agent tool using the
same vv-harness agent types
(vv-harness:feature-implementer, vv-harness:layer-implementer,
vv-harness:researcher, vv-harness:reviewer), passing isolation: "worktree" at
spawn time for independent feature scopes — worktree isolation is documented platform
behavior for subagents. The lead merges the worktree branches at synthesis (Phase 4).
This is the supported, non-experimental path. Team-only machinery does not apply in this mode: no SendMessage interface negotiation, no TeammateIdle reassignment — sequencing falls back to the lead, which spawns dependent work only after its prerequisites are merged.
Ask the user if it's ambiguous:
I see [N] features ready. I can either:
1. Work on F00X in a focused single session
2. Spawn a team to work on F00X and F00Y in parallel
Which do you prefer?
features.json: set status to "in-progress", set assigned_to to "single-session"TaskCreate({ subject: "F001: Read existing code in [scope directories]", description: "Understand patterns before implementing", activeForm: "Reading existing code", metadata: { feature_id: "F001" } })
TaskCreate({ subject: "F001: Write failing test for [feature]", description: "[feature description] — TDD red phase", activeForm: "Writing failing test", metadata: { feature_id: "F001" } })
TaskCreate({ subject: "F001: Implement minimum code to pass", description: "TDD green phase", activeForm: "Implementing feature", metadata: { feature_id: "F001" } })
TaskCreate({ subject: "F001: Run full test suite", description: "Verify no regressions", metadata: { feature_id: "F001" } })
TaskCreate({ subject: "F001: Verify coverage >= 95% on touched code", description: "Coverage gate", metadata: { feature_id: "F001" } })
TaskCreate({ subject: "F001: Update features.json", description: "Set status to passing, populate test_file and coverage", metadata: { feature_id: "F001" } })
TaskCreate({ subject: "F001: Update context_summary.md with learnings", description: "Persist decisions and patterns", metadata: { feature_id: "F001" } })
Use TaskUpdate to mark each task in_progress when starting and completed when done. Task updates must happen at the moment of state change, not in batch. The rule: when you finish something, the NEXT action is TaskUpdate — before responding to the user, before starting the next task. If planned tasks no longer match reality (scope changed, new work appeared), update or delete stale tasks immediately. A stale task list is worse than no task list because it creates false confidence about state.
./.harness/init.shin_progressin_progresscompletedNo exceptions unless tooling is broken.
Treat context_summary.md updates as part of the task, not after the task. Specifically: after every bug fix that reveals a non-obvious root cause, write the gotcha to context_summary.md BEFORE moving to the next request. The cost is 30 seconds; the value is permanent. A future session will benefit from knowing the root cause without re-discovering it.
For the context_summary.md structure and section-by-section update rules, read ${CLAUDE_PLUGIN_ROOT}/rules/context-summary.md.
.harness/features.json: set status to "passing", add test_file and coverage, clear assigned_to. Also populate approaches_tried with a brief note on what worked (even for single-session work — this feeds the retrospective)..harness/context_summary.mdfeatures.json with discovered_via pointing to this feature's ID.If approaching context limit, compact at a clean breakpoint:
Before compacting, ensure:
context_summary.md has any important context that must surviveUse /compact with a focus instruction, e.g.:
/compact Focus on: current feature F003 state, TDD progress, decisions made about auth architecture
After compaction, the plugin's SessionStart hook (matcher compact) automatically
injects a recovery block plus fresh orientation: re-read .harness/context_summary.md
Active Context and the task list. Follow it — it's your recovery path.
features.json against the actual work done this session. If any code was changed that relates to a tracked feature, that feature's metadata must be updated (status, test_file, coverage). If work was done that doesn't map to any existing feature, create a new feature entry with discovered_via pointing to the trigger. This check is a gate before git commit, not an afterthought.context_summary.md under ## Meta-Session [DATE] before the final commit. Skip only if this is the project's very first session.claude-progress.txt:
## Session [N] - [DATE]
- Feature: F00X - [description]
- Status: [complete | in-progress | blocked]
- Tests: [N passing, M failing]
- Coverage: [X%] on touched code
- Decisions: [brief list, details in context_summary.md]
- Next: [what the next session should do]
- Blockers: [any blockers]
Before declaring the session complete, work through the full checklist in ${CLAUDE_PLUGIN_ROOT}/rules/task-completion.md (base checklist plus the harness-specific additions).
Before any team coordination, Read the Agent Teams protocol at
${CLAUDE_PLUGIN_ROOT}/rules/agent-teams-protocol.md. Agent Teams is experimental and
gated by CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1; the team forms implicitly when the
first teammate is spawned (no setup step) and is cleaned up automatically when the
session ends. This workflow uses Claude Code's native primitives: the Agent tool for
spawning, TaskCreate, TaskUpdate, TaskList, and SendMessage.
Before spending tokens on teammates, produce a decomposition plan:
.harness/features.jsonscope and depends_on from each feature to identify parallelism opportunities and dependency chainscorrection_cycles >= 3 in the same scope directories → upgrade implementer to Opusscope_expansions >= 3 → assign a broader initial scope to reduce mid-work expansion overheaddiscovered_via depth > 1 → consider folding them into the parent feature's scopescope field), what model (Sonnet default; Opus if historical metrics suggest high difficulty). The plugin agent definitions already default the model per role (implementers and researcher: Sonnet; reviewer: Opus); a spawn-time model parameter overrides the definition's frontmatter, so an Opus upgrade needs only the Agent tool call's model param.depends_on field, mapped to TaskUpdate addBlockedBy calls after task creation)require_plan_approval: trueI propose this team structure:
Lead (Opus, plan mode): coordination, synthesis, final review
Teammate "api" (Sonnet): F001 - owns src/api/ and tests/api/
Teammate "ui" (Sonnet): F002 - owns src/components/ and tests/components/
→ blocked by "api" (F002 depends_on F001)
Teammate "reviewer" (Opus): reviews both after completion
Dependencies (from features.json):
Task 1 (F001 API) → unblocks Task 2 (F002 UI)
Tasks 1+2 → unblock Task 3 (review)
Plan approval required: No (scopes are straightforward)
Estimated: 3 teammates × Sonnet + 1 reviewer × Opus
Note: Opus lead runs for the full session; total cost depends on session length, not just implementer tokens.
Approve this plan?
Wait for user approval before proceeding to Phase 2. That approval is durable: it covers execution through to the approved goal's completion. Do not stop for further go-aheads at phase transitions; return to the user only when the goal is accomplished, the work is blocked, or the approved plan itself must change.
Activate plan mode (Shift+Tab) to restrict yourself to coordination-only tools. Do not edit code directly.
Update features.json: set assigned_to for each feature being worked on.
Confirm CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 is set. There is no team-creation
step: the implicit team forms when the first teammate is spawned (Step 5) and is
cleaned up automatically when the session ends.
Create tasks with feature metadata, then set dependency chains (derived from features.json depends_on):
# Create all tasks first (they start as pending by default)
# Always include metadata.feature_id — hooks and TaskList use it for correlation
TaskCreate({ subject: "F001: Build API endpoint", description: "[detailed spec]", activeForm: "Building API endpoint", metadata: { feature_id: "F001", scope: "src/api/", model: "sonnet" } })
# → task id "1"
TaskCreate({ subject: "F002: Build UI consuming API", description: "[detailed spec]", activeForm: "Building UI layer", metadata: { feature_id: "F002", scope: "src/ui/", model: "sonnet" } })
# → task id "2"
TaskCreate({ subject: "Review F001 + F002", description: "[review criteria]", activeForm: "Reviewing implementation", metadata: { feature_id: "F001,F002", scope: "*", model: "opus" } })
# → task id "3"
# Then set dependencies via TaskUpdate
TaskUpdate({ taskId: "2", addBlockedBy: ["1"] })
TaskUpdate({ taskId: "3", addBlockedBy: ["1", "2"] })
Spawn teammates as the vv-harness plugin agent types. Each definition bakes in the
role's reusable guardrails (TDD discipline, tool allowlist, scope rules, completion
protocol), so the spawn prompt carries only per-feature specifics — use the templates
from team-spawn-prompts.md in this skill's directory:
Agent({
description: "Implement F001",
subagent_type: "vv-harness:feature-implementer",
name: "api",
model: "sonnet",
prompt: "[per-feature specifics: feature ID, scope from features.json, deliverable, git identity, plan-approval flag, task ID]"
})
The name makes the teammate addressable via SendMessage; the team it joins is
implicit, so there is no team_name to pass (the parameter is accepted but ignored).
Agent types: vv-harness:feature-implementer, vv-harness:layer-implementer,
vv-harness:researcher, vv-harness:reviewer. The spawn-time model parameter
overrides the definition's frontmatter model, so the Phase 1 Opus-upgrade heuristic
applies unchanged. Include git identity from harness.json in each spawn prompt.
Do not re-paste guardrail prose into spawn prompts — it lives in the agent definitions.
The spawn tool is exposed as Agent (older CLIs called it Task); adapt to what your
CLI exposes.
At team start, confirm plan-approval messaging uses type "message" (the
plan_approval_response delivery-bug workaround) — one SendMessage round-trip with a
teammate is the check; if it fails on a newer CLI, fall back to the worktree-subagent
mode (Step 4, graceful degradation).
TaskList for progressSendMessage messages:
SendMessage (type "message", not "plan_approval_response" which has a delivery bug)The TeammateIdle hook prompts idle teammates to pick up remaining features, so you don't need to manually reassign after each task completes.
When all teammates complete:
git diffcontext_summary.md.harness/features.json for each completed feature (status, test_file, coverage, clear assigned_to).harness/context_summary.mdWhen all features reach status: "passing", run a metacognitive retrospective before teardown. This is the mechanism by which the harness improves its own coordination — not just the domain code.
Review the operational metrics across all features completed this session:
scope_expansions > 0? What does that reveal about how to scope similar work next time? (e.g., "auth/ and user/ are coupled — scope them together")correction_cycles >= 3? Were they on Sonnet? If yes, note that similar-scope features should use Opus.discovered_via set? Does the discovery pattern suggest the initial feature decomposition missed something systematic?approaches_tried worked repeatedly? What failed repeatedly?require_plan_approval prevent rework, or was it overhead? Note which feature types benefited.Write findings to .harness/context_summary.md under a new ## Meta-Session [DATE] section:
## Meta-Session 2026-03-23
- Scope accuracy: [findings — which scopes needed expansion and what that means]
- Model calibration: [which features burned correction cycles on Sonnet; upgrade recommendation]
- Discovery lineage: [which features were discovered mid-work; what to probe for at init time]
- Approach patterns: [what worked, what failed]
- Plan approval: [was it worth the overhead for which feature types]
When to skip: If this is the first session (no historical data in features.json operational metrics), skip the retrospective — there's nothing to analyze yet. Write a note: ## Meta-Session [DATE] — first session, no retrospective data yet.
Write findings to ## Meta-Patterns for insights that generalize beyond this session:
## Meta-Patterns
- [Insight that applies to future sessions, not just this domain]
Do NOT write domain-specific decisions here — those go in the Domain sections. Meta-Patterns are coordination insights: when to use Opus, how to scope, when to require plan approval.
shutdown_request to all teammates via SendMessageshutdown_response from eachclaude-progress.txt:
## Session [N] - [DATE] (Agent Teams: [N] teammates)
- Teammates: [name (model): scope] for each
- Tasks: [N completed, M blocked, P pending]
- Features completed: [list]
- Features in-progress: [list]
- Dependencies resolved: [any chains that unblocked]
- Integration issues: [any conflicts resolved, details in context_summary.md]
- Tests: [N passing, M failing]
- Cost note: [models used, if relevant]
- Next: [what the next session should do]
All high-priority features are complete: Report to user. Ask if there are new features to add or if the project is done.
Feature is blocked:
Document the blocker in claude-progress.txt and context_summary.md. Move to the next available feature.
Tests are failing from a previous session: Fix them before starting new work. This is priority zero.
Context is getting heavy mid-session:
Compact at the next clean breakpoint. Task list should already be current (you're updating after every step). Ensure context_summary.md has any important context, then /compact.
Teammate crashes or stalls:
The 5-minute heartbeat timeout will notify the lead. Spawn a replacement teammate for the stalled scope, or take over the scope directly (exit plan mode). Update assigned_to in features.json.
Lead session interrupted:
In-process teammates are lost if the lead dies. teammateMode defaults to "in-process", so set it explicitly (tmux or auto) for long-running team sessions that might be interrupted. On restart, read claude-progress.txt, features.json (check assigned_to fields), and context_summary.md to reconstruct state. Features with assigned_to set but status still in-progress were likely interrupted mid-work.
Integration failure between teammates: Follow the Integration Failure Recovery protocol in agent-teams-protocol.md. Prioritize getting back to green tests over preserving partial work.
npx claudepluginhub oeftimie/vv-claude-harness --plugin vv-harnessInitializes a new project with the Long-Running Agent Harness (vv-harness plugin), setting up feature tracking, git identity capture, context summary, build hooks, quality gate hooks, and optional Agent Teams structure. Use when starting a new multi-session project.
Executes Plans.md tasks end-to-end in solo, parallel, or full team modes with auto-mode selection based on task count.
Runs a complete feature lifecycle from GitHub issue/branch creation through ATDD implementation, verification, commit/push/PR, and merge. Supports batch processing, plan-only mode, and team-based acceptance test-driven development.