Skip to content
Back to skills

Wf Quit

ASecurity

Cleanly stops the active wf workflow — shutdown teammates, marker cleanup, state preservation for resume.

  • 2 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added May 26, 2026
ai-agentsbashgit

Works with

  • claude code

Security analysis

A100/100

Scanned May 27, 2026

npx -y skills add mgallet92i/waterfall --skill wf-quit --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Wf Quit?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Wf Quit
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/mgallet92i-wf-quit/badge)](https://www.skillsdirectory.com/skills/mgallet92i-wf-quit)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: wf-quit
description: Cleanly stops the active wf workflow — shutdown teammates, marker cleanup, state preservation for resume.
user-invocable: false
allowed-tools: Read, Bash(bash *), SendMessage
---

# wf-quit — Clean shutdown of the active workflow

This skill is invoked by `/waterfall:quit`. It stops the active team of the current session, cleans up session markers, and preserves the need's state for resumption via `/waterfall:resume`.

## Step 1 — Detect the active session

Read the current `session_id` from the environment or the Claude Code session context.

Check whether the session marker exists:
```
~/.claude/wf-session-active.<session_id>
```

If the file **does not exist**: display the following message and stop (exit 0):
```
No active wf workflow in this session.
```
(EX-011 — no error, neutral behavior)

If the file **exists**: read its content to obtain the `need_name`:
```bash
need_name=$(cat ~/.claude/wf-session-active.<session_id>)
```

## Step 2 — Load the team config

Build the config path:
```
~/.claude/teams/wf-<need_name>/config.json
```

Read the JSON to enumerate active teammates (field `teammates` or equivalent depending on harness format).

If the file is missing or corrupted: continue with an empty teammates list (R4 fallback — markers will be deleted anyway, teammates will time out on the harness side).

## Step 3 — Send shutdown_request to each teammate

For each active teammate identified in step 2, send via `SendMessage` (plain text):
```
to: <teammate_name>
message: |
  type: shutdown_request
  request_id: wf-quit-<session_id>
```

Send messages in parallel if possible. Do not wait for a response (`shutdown_response`) — the shutdown is unilateral.

## Step 3.bis — Close the active segment (ADR-008)

Before deleting markers, close the current segment in `.wf-state.json`:

```bash
state_file="wf/needs/$need_name/.wf-state.json"
source "${CLAUDE_PLUGIN_ROOT}/scripts/lib/wf-segments.sh"
_seg_close "$state_file" || true
```

This operation is atomic (jq + tmp + mv). If the file does not exist or jq fails, the error is silently ignored (robustness R4).

## Step 3.ter — CronDelete watchdog if close_requested (EX-WCC-004)

If the watchdog wrote a close flag in `status.json`, wf-quit handles the `CronDelete` as a safety net (INV-WCC-002: wf-quit is on the HO side, therefore allowed to call CronDelete).

```
if ~/.claude/wf-watchdog-status.json exists:
  cron_id = jq -r '.cron_job_id // ""' ~/.claude/wf-watchdog-status.json
  close_req = jq -r '.close_requested // false' ~/.claude/wf-watchdog-status.json
  if close_req == "true" AND cron_id non-empty:
    CronDelete(cron_id)
    log cron_deleted_via_quit in or.log:
      bash ${CLAUDE_PLUGIN_ROOT}/scripts/wf-orchestrate.sh <name> --log \
        --msg '{ "ts": "<now>", "tag": "[WATCHDOG]", "event": "cron_deleted_via_quit", "cron_job_id": "<cron_id>" }'
else: silent skip
```

> **INV-WCC-003**: do not delete `~/.claude/wf-watchdog-status.json` — the file remains with `status=OFF` for statusline consistency. PM cleans the `close_requested` / `cron_job_id` fields via `del()` if it runs after.

## Step 4 — Need-scoped marker cleanup (ADR-004)

Read the `session_id` **from the need's `.wf-state.json`** (not from the current env — avoids deleting markers from another window if `/waterfall:quit` is run out of context):

```bash
sid_besoin=$(jq -r .session_id "wf/needs/$need_name/.wf-state.json")
rm -f "$HOME/.claude/wf-session-active.$sid_besoin"
```

These deletions are:
- **Idempotent**: `rm -f` — no error if files already absent (EX-011)
- **Cross-window safe**: based on the sid stored in the state, not on `$CLAUDE_SESSION_ID` of the current window (ADR-004, INV-005)
- **Non-destructive** on `.wf-state.json` (EX-012 / INV-004)

## Step 5 — Display confirmation

Display a confirmation message, for example:
```
Workflow wf-<need_name> stopped.
Teammates received shutdown_request.
Session markers deleted.

To resume: /waterfall:resume <need_name>
```

## Rules

- **ALLOWED only**: close the active segment via `_seg_close` (step 3.bis) — the only mutation permitted on `.wf-state.json`
- **FORBIDDEN**: any other modification of `.wf-state.json` (phase, step, status, history — EX-012 / INV-004)
- **FORBIDDEN**: `git commit`, archiving, modification of SDD artifacts
- **Idempotent**: if called twice, no error (rm -f in the helper)
- **Neutral if no session**: informational message, exit 0 (EX-011)

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.