Skills Reference Home
●  Harness System

Harness and Skills Reference

The autonomous agent harness: 16 core skills, 5 rule files, and an UNATTENDED session model that lets Slop implement issues without any human input.

6 daemon-dispatched 10 agent-invocable 5 rule files UNATTENDED mode Session resume

The Harness

The harness lives in harness/ and is deployed into each watched repo via harness/bootstrap.sh. When a Claude Code agent runs in a worktree for that repo it automatically picks up all rules and skills.

harness/
  bootstrap.sh                   # Deploys harness into a watched repo
  .claude/
    CLAUDE.md                    # Global instructions for all agent sessions
    rules/                       # Five rule files (commits, safety, interaction, testing, tools)
  skills/core/
    implement-issue/             # Main implementation skill (daemon-dispatched)
    fix-ci/                      # CI failure repair (daemon-dispatched)
    resolve-conflict/            # Merge conflict resolution (daemon-dispatched)
    verify-gate/                 # Pre-ship verification gate (daemon-dispatched)
    pr-review/                   # Adversarial PR reviewer (daemon-dispatched)
    address-comments/            # Address reviewer findings (daemon-dispatched)
    cover/  review/  merge/  ...  # Agent-invocable skills

UNATTENDED Mode

Every agent session Slop launches must proceed autonomously with no human in the loop. Two layers enforce this.

UNATTENDED_SYSTEM_PROMPT

  • Injected into every session's system prompt by the daemon
  • Forbids calling AskUserQuestion
  • Requires terse output (one sentence per status update)
  • Instructs the agent to proceed without requesting confirmation

PreToolUse Hook (safety net)

  • Hard-blocks AskUserQuestion at the tool level
  • Blocks git stash mutating subcommands (push, pop, apply, drop)
  • Reason: worktrees share the main repo's stash stack -- stashing in a worktree contaminates unrelated branches
Session resume: The daemon captures Worker.sessionId from the agent's system.init event. On daemon restart, workers in implementing or verifying are re-dispatched with resumeSessionId pointing to the old session. The agent resumes the surviving session rather than re-implementing from scratch. Codex workers (no session persistence) restart fresh from the preserved worktree.

All 16 Core Skills

Orange badge = launched by the daemon as a new agent session. Blue badge = called by the implementing agent from within its own session.

/implement-issue daemon
Budget: 1 attempt (+ session resume on restart)

The main implementation skill. Fetches the issue, runs quality gates, commits, pushes, and opens a PR (or merges locally).

/fix-ci daemon
Budget: maxCiAttempts (default 5)

Reproduces a failing CI check, fixes the root cause, force-pushes with --force-with-lease.

/resolve-conflict daemon
Budget: maxConflictAttempts (default 5)

Rebases onto the base branch, resolves every conflict preserving intent, runs fast checks, force-pushes.

/verify-gate daemon
Budget: maxVerificationAttempts (default 5)

Runs /cover and /review. Emits exactly one final line: SLOP_VERDICT: pass or SLOP_VERDICT: findings.

/pr-review daemon
Budget: maxReviewAttempts (default 3)

Adversarial reviewer. Posts one COMMENT-event review with inline findings prefixed reviewer:. Verdict line: reviewer: **Verdict: ...**.

/address-comments daemon
Budget: shared with maxReviewAttempts

Responds to reviewer: threads: fixes, declines, or questions each. One git push at the end. Replies prefixed addresser:.

/cover agent
Called from /verify-gate

Writes meaningful tests for new or under-tested behavior. Every test must be able to fail. No coverage-percentage targets.

/review agent
Called from /verify-gate or inline

Adversarial pre-ship review. Four lenses: Intent, Scope, Conventions, Specialist (security/perf/correctness).

/merge agent
End of /one-shot flow

Remote: push + PR + poll + merge. Local: squash-merge into base, remove worktree, close issue.

/one-shot agent
Ad-hoc, no issue required

Free-form implementation in an isolated worktree. Implements, commits, stops. User runs /merge to finish.

/root-cause agent
Bug investigation

Reproduces, bisects, fixes at the root (not the symptom), adds a regression test that fails before and passes after.

/design-pass agent
After UI implementation

Applies docs/DESIGN.md to freshly-written UI. Fixes raw colors, broken hierarchy, missing empty/error/loading states.

/ux agent
Flow audit

Walks critical flows with Playwright MCP, judges IA and navigation. Diagnoses only -- does not write UI code.

/release agent
Release management

Updates GitHub draft release with Keep-a-Changelog notes, builds preview via make release, deploys via make ship.

/fix-base-ci daemon
Base branch CI is red

Fixes CI on the base branch itself (not a PR branch). Opens a separate PR targeting the base. Invoked by fixBaseCi().

/clear-reviews agent
Reset review conversation

Deletes all reviewer: and addresser: comments from a PR. Used to reset before re-running /pr-review from scratch.

Daemon-Dispatched Skills

The daemon spawns a fresh agent session for each of these. The session runs in the issue's worktree with the UNATTENDED system prompt injected.

/implement-issue daemon
trigger: issue claimed args: reuse-worktree <N>

The reuse-worktree modifier tells the skill the daemon already ran git worktree add and installed dependencies. The agent calls worktree-setup.sh --reuse, which exports the worktree path variables without touching git.

Six steps: (1) fetch issue from internal HTTP store, (2) resolve shipping mode, (3) worktree setup via --reuse, (4) implement and run quality gate, (5) update docs, (6) commit + push + gh pr create. The PR body never contains "Closes #N" -- Slop closes the issue directly via closeWorkerIssue().

# Step 1 - fetch issue (never gh issue view -- numbers collide)
GET $SLOP_URL/api/internal-issues?repo=$SLUG
# filter: .find(i => i.number === N)

# Step 6 - commit and ship (remote mode)
git commit -m "feat: <summary>"
git push -u origin slop/issue-<N>
gh pr create --title "..." --body "..."
/fix-ci daemon
trigger: CI check failed budget: maxCiAttempts (5)

Rebases onto the latest base, reproduces the failing check, fixes the root cause, and force-pushes. The existing PR updates automatically. Never opens a new PR. Never uses git stash or git rebase -i (interactive mode is not supported in unattended sessions).

git fetch origin <base> && git rebase origin/<base>
# reproduce, fix, then:
git push --force-with-lease
/resolve-conflict daemon
trigger: PR merge status is dirty budget: maxConflictAttempts (5)

Rebases onto the base branch and resolves every conflict in place, preserving the intent of both sides. Runs lint, typecheck, and tests as a fast sanity check, then force-pushes (remote) or leaves the branch clean (local mode, no push).

/verify-gate daemon
trigger: verifyGate = true in config budget: maxVerificationAttempts (5)

Reads .slop-verify-context.json written by the daemon before launching the session:

{ "issueNumber": 42, "implementGateSha": "abc123", "docsOnly": false }

If implementGateSha matches HEAD, tests were already green at the end of the implement session -- the verify-gate skips re-running tests and goes straight to /review. Always ends with exactly one line: SLOP_VERDICT: pass or SLOP_VERDICT: findings.

/pr-review daemon
trigger: autoReviewMode = true + CI green budget: maxReviewAttempts (3)

The PR is assumed wrong until proven otherwise. Three rules: (1) every finding cites file:line from the diff or source, (2) collect findings first, add fixes after verification, (3) style never blocks a merge.

Posts one COMMENT-event review with inline comments all prefixed reviewer:. Verdict line:

reviewer: **Verdict: pass**
-- or --
reviewer: **Verdict: request_changes**

On re-review (after /address-comments): walks all threads and resolves settled ones via GraphQL resolveReviewThread.

/address-comments daemon
trigger: verdict = request_changes budget: shared with maxReviewAttempts

Reads every reviewer: thread and responds to each finding individually. For each finding it either fixes (edits code, stages, replies addresser: fixed in <sha>), declines (addresser: declined - <file:line evidence>), or questions (addresser: question - ...). All fixes are pushed in one git push at the end, then a wrap-up summary comment is posted at the PR top level. Worker returns to waiting_ci after addressing.

Harness Rules

Five rule files in harness/.claude/rules/ govern agent behavior across all sessions. Every agent that runs in the watched repo picks these up automatically.

Commit Format commits.md
  • Format: <type>: <imperative summary>
  • Types: feat / fix / refactor / chore / docs / test / perf
  • Lowercase, no trailing period, max 72 chars
  • Body only when the "why" is not obvious from the summary
Git Safety git-safety.md
  • Never force push to main or master
  • Never amend published commits
  • Never skip hooks (--no-verify)
  • Stage by name -- never git add -A
Interaction interaction.md
  • Use AskUserQuestion for enumerable choices only
  • Ask one question at a time during interviews
  • For audits/reviews: write full findings first, then ask
  • No narration between tool calls ("Reading...", "Now I'll...")
Testing testing.md
  • Run tests before declaring a task complete
  • Prefer integration tests over mocked unit tests
  • Update tests when changing tested behavior
  • Never skip/xfail tests to make the suite pass
Tool Discipline tool-discipline.md
  • Redirect output to a file; use Read/Grep to inspect it
  • Read every file before its first Edit
  • Copy old_string verbatim -- whitespace must match exactly
  • Run formatter exactly once, as the first quality gate step
  • Never git stash in a worktree (shared stash stack)

Internal Issues API

Skills use the Slop HTTP API to interact with internal issues. They never call gh issue view directly because GitHub issue numbers and internal issue numbers can collide when both trackers are active for the same repo.

GET
/api/internal-issues?repo=<owner/name>
List all internal issues for a repo. Filter client-side to find by number.
GET
/api/internal-issues/<uuid>
Fetch one issue by UUID. The id field is a UUID, not the display number.
POST
/api/internal-issues
Create an issue. Body: { repoId, title, body?, labels? }
PATCH
/api/internal-issues/<uuid>
Update an issue. Body: { title?, body?, labels? }
# Look up an issue by number (list + filter)
curl -fsS "$SLOP_URL/api/internal-issues?repo=owner/name" \
  | python3 -c "import json,sys; issues=json.load(sys.stdin); \
    print(next(i for i in issues if i['number']==42)['id'])"

# Create an internal issue
curl -fsS -X POST "$SLOP_URL/api/internal-issues" \
  -H "Content-Type: application/json" \
  -d '{"repoId":"<id>","title":"Fix the thing","body":"Details..."}'

worktree-setup.sh

Located at harness/skills/core/implement-issue/scripts/worktree-setup.sh. Used by /implement-issue to configure the worktree environment. Two modes:

Standard Mode (user-invoked)

  • Creates a new worktree with git worktree add -b feature/<slug> <path> origin/<base>
  • Copies .env* files from the main checkout
  • Seeds .env.local from .env.example if absent
./worktree-setup.sh feature-name

--reuse Mode (daemon-invoked)

  • Adopts the current working directory as the worktree (no git ops)
  • Exports IMPLEMENT_ISSUE_MAIN, IMPLEMENT_ISSUE_WT, IMPLEMENT_ISSUE_BRANCH
  • Daemon already ran git worktree add and installed deps
./worktree-setup.sh --reuse
Why reuse? The daemon pre-creates the worktree and runs installDepsInWorktree() (which auto-detects pnpm/yarn/npm from lockfiles) before launching the agent session. This way dependency installation happens outside the session budget, and the agent starts with a fully ready environment.