monoes

mastermind-stoporg

Mastermind stoporg — stop a running scheduled org loop by setting its status to "stopped". The next scheduled wakeup will read the status, skip all work, and not reschedule. Loop dies within one interval — no orphaned wakeups.

monoes 23 2 Updated 1mo ago
GitHub

Install

npx skillscat add monoes/monomind/mastermind-stoporg

Install via the SkillsCat registry.

SKILL.md

Mastermind Stop Org

This skill is invoked by mastermind:stoporg or directly via /mastermind:stoporg.


Inputs

  • org_name: name of the org to stop (matches .monomind/orgs/<org_name>.json)
  • session_id: session ID generated by the command wrapper
  • caller: command | master

Step 0 — Brain Load (standalone only)

If caller is not "command", load brain context following mastermind-protocol/SKILL.md Brain Load Procedure with namespace: ops.


Step 1 — Validate Org

orgFile=".monomind/orgs/${org_name}.json"
[ ! -f "$orgFile" ] && {
  echo "ERROR: Org '${org_name}' not found."
  echo "Available orgs: $(ls .monomind/orgs/*.json 2>/dev/null | grep -vE -- '-approvals|-state|-activity|-goals|-routines|-projects|-members|-issues|-workspaces|-worktrees|-environments|-plugins|-adapters|-bootstrap|-threads|-budgets|-project-workspaces|-approval-comments' | xargs -I{} basename {} .json | tr '\n' ' ')"
  exit 1
}

Read current status:

current_status=$(jq -r '.status // "no-schedule"' "$orgFile")
has_schedule=$(jq -r 'if .loop.poll_interval_minutes then "yes" else "no" end' "$orgFile")

If has_schedule == "no" — this is a v2 org (Org Runtime v2 has schedule,
never .loop). Its daemon polls .monomind/orgs/<name>/stop every 2s, which is
exactly what monomind org stop writes — use the CLI, not the v1 .stops/ path:

REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
CTRL_URL=$(jq -r '.url // "http://localhost:4242"' "$REPO_ROOT/.monomind/control.json" 2>/dev/null || echo "http://localhost:4242")
npx -y monomind@latest org stop "${org_name}" \
  || { mkdir -p ".monomind/orgs/${org_name}"; date -u +%Y-%m-%dT%H:%M:%SZ > ".monomind/orgs/${org_name}/stop"; }
# Also POST to the control server in case a dashboard-started instance is running
curl -s -X POST -H "x-monomind-token: $(cat "${REPO_ROOT:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}/.monomind/dashboard-token" 2>/dev/null || true)" "${CTRL_URL}/api/orgs/${org_name}/stop" >/dev/null 2>&1 || true
echo "Stop requested for org '${org_name}' (v2 daemon exits within 2s)."
  • Exit.

Everything below this point only runs for v1 orgs — v2 orgs already exited above.

If current_status == "stopped":

  • Print: "Org '' is already stopped."
  • Exit.

Step 2 — Set Status to Stopped and Clear next_run (v1 only)

orgFile=".monomind/orgs/${org_name}.json"
tmp="${orgFile}.tmp"
# Clear next_run to avoid showing a stale future timestamp in orgstatus
jq '.status = "stopped" | if .loop then .loop.next_run = null else . end' "$orgFile" > "$tmp" && mv "$tmp" "$orgFile"

Step 3 — Write Stop File (for any running boss agents, v1 only)

Any persistent boss agent checks for this file at the start of each loop iteration:

mkdir -p .monomind/orgs/.stops
touch ".monomind/orgs/.stops/${org_name}.stop"

Step 5 — Report to User (v1 only)

✓ Org "<org_name>" stopped.

  Current status: stopped
  The loop will exit at its next scheduled wakeup without rescheduling.
  Loop fully dead within: ≤$(jq -r '.loop.poll_interval_minutes // "?"' "$orgFile") minutes

  To restart: /mastermind:runorg --org <org_name>
  Status:     /mastermind:orgstatus --org <org_name>

Step 6 — Return Output

domain: ops
status: complete
decisions:
  - what: "Org <org_name> stopped"
    why: "status set to 'stopped'; next wakeup exits without rescheduling"
    confidence: 1.0
    outcome: shipped
next_actions:
  - "To restart: /mastermind:runorg --org <org_name>"
  - "To check current state: /mastermind:orgstatus --org <org_name>"

Step 7 — Brain Write (standalone only)

If caller is not "command", follow mastermind-protocol/SKILL.md Brain Write Procedure for domain ops.