Receber por email
← Voltar para o catálogo

phase-remediate

Phase-agent that fixes a failing verify verdict so the pipeline self-heals instead of stalling to needs-human (CTL-653). Reads `${ORCH_DIR}/workers/<ticket>/verify.json`, fixes the `findings[]` (every severity:"high" plus the regression_risk drivers) directly via Edit/Write, commits the remediation, and emits `phase.remediate.complete.<ticket>`. The scheduler's router then re-dispatches `verify` t

18estrelas
Atualizado há 3 meses

Ver no GitHub ↗

Como adicionar

/plugin marketplace add coalesce-labs/catalyst

O comando exato pode variar conforme o repositório. Confira o README no GitHub.

Para o autor da skill

Cole no README do seu repo

Mostra que sua skill está catalogada na Skillteca, gera backlink e tráfego rastreável.

[![Skillteca](https://www.skillteca.com.br/api/badge/phase-remediate/svg)](https://www.skillteca.com.br/skills/phase-remediate)
#ai

Skills relacionadas

Ver todas de Marketing →

Alerta por categoria

Receba novas skills de Marketing toda segunda

1 email curto, só com as skills novas de Marketing. 4 minutos de leitura, sem spam, cancela com 1 clique.

Você confirma o email no primeiro envio. Sem spam. Cancela com 1 clique.

Ler descrição completa

phase-remediate

Phase-agent that owns the fix half of the verify⇄remediate cycle (CTL-653). Today a failing verify is a dead-end: the router marches into review against a known-bad branch, or a verify crash revives once then stalls to needs-human. phase-remediate is the conditional detour the router takes when verify produces a verdict-fail (regression_risk ≥ 5 OR any severity:"high" finding): it reads verify.json.findings[] as its brief, fixes the code, commits, and hands back to a fresh verify. The loop repeats up to 3 times before escalating — so a verify failure self-heals autonomously.

Unlike phase-implement (a thin wrapper around /catalyst-dev:implement-plan), there is no canonical "fix-findings" skill to delegate to — the fix work lives in this skill body. It is otherwise the same fix-capable envelope (Edit/Write/Task, CTL-615 yield check, CTL-632 Linear mirror, terminal emit).

Prerequisites

  • CATALYST_ORCHESTRATOR_DIR, CATALYST_ORCHESTRATOR_ID, CATALYST_PHASE=remediate, CATALYST_TICKET set by [[phase-agent-dispatch]].
  • A verify.json exists at ${ORCH_DIR}/workers/<ticket>/verify.json — the dispatcher's prior-artifact gate (signal:verify.json) already validates this; this skill re-reads it.
  • Current working directory is the ticket's worktree (already carries the implement-phase commits).

Prelude (template — copy verbatim into the running session)

set -euo pipefail

: "${CATALYST_ORCHESTRATOR_DIR:?required (set by phase-agent-dispatch)}"
: "${CATALYST_ORCHESTRATOR_ID:?required}"
: "${CATALYST_PHASE:?required}"
: "${CATALYST_TICKET:?required}"

ORCH_DIR="$CATALYST_ORCHESTRATOR_DIR"
ORCH_ID="$CATALYST_ORCHESTRATOR_ID"
PHASE="$CATALYST_PHASE"
TICKET="$CATALYST_TICKET"
CHANNEL="${ORCH_ID}"

# CTL-484: continuation-worker orientation. Set by orchestrate-revive's
# continuation branch when this skill is resumed via `claude --bg --resume`
# after a previous session hit its /goal turn cap. Read the handoff doc and
# trust its summary instead of re-deriving the fix set from scratch.
if [[ "${CATALYST_IS_CONTINUATION:-}" == "true" ]]; then
  CONT_HANDOFF="${CATALYST_HANDOFF_PATH:-}"
  CONT_N="${CATALYST_CONTINUATION_COUNT:-?}"
  if [[ -n "$CONT_HANDOFF" && -f "$CONT_HANDOFF" ]]; then
    echo "phase-remediate: continuation #${CONT_N} — resuming from ${CONT_HANDOFF}"
    echo "phase-remediate: reading handoff (do NOT re-derive the fix set from scratch)"
    cat "$CONT_HANDOFF"
  else
    echo "warn: CATALYST_IS_CONTINUATION=true but handoff path missing or unreadable" >&2
  fi
fi

SIGNAL_FILE="${ORCH_DIR}/workers/${TICKET}/phase-${PHASE}.json"
[[ -f "$SIGNAL_FILE" ]] || { echo "phase-${PHASE}: signal file missing" >&2; exit 1; }

PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT:-}"
[[ -n "$PLUGIN_ROOT" ]] || PLUGIN_ROOT="$(dirname "$(dirname "$(dirname "$(realpath "${BASH_SOURCE[0]:-$0}" 2>/dev/null || echo .)")")")"

# 0. Codified bg_job_id yield (CTL-615). If the signal file's bg_job_id names a
#    DIFFERENT live bg job, we are a redispatch duplicate of a still-running
#    canonical worker. Bow out without touching the signal, without emitting any
#    phase event. Encodes operator memories #43/#44/#49/#50. phase-remediate
#    commits code (like implement), so it carries the gate.
YIELD_CHECK="${PLUGIN_ROOT}/scripts/phase-agent-yield-check.sh"
if [[ -x "$YIELD_CHECK" ]] && bash "$YIELD_CHECK" \
     --signal "$SIGNAL_FILE" \
     --phase "$PHASE" \
     --worker-dir "$(dirname "$SIGNAL_FILE")"; then
  echo "phase-${PHASE}: yielding to canonical worker (CTL-615)" >&2
  exit 0
fi

# 1. Join the shared comms channel (best-effort).
COMMS="${PLUGIN_ROOT}/scripts/catalyst-comms"
[[ -x "$COMMS" ]] || COMMS="$(command -v catalyst-comms 2>/dev/null || true)"
if [[ -n "$COMMS" && -x "$COMMS" ]]; then
  "$COMMS" join "$CHANNEL" --as "$TICKET" \
    --capabilities "phase-remediate: ${TICKET}" \
    --orch "$ORCH_ID" --parent orchestrator --ttl 3600 >/dev/null 2>&1 || true
  "$COMMS" send "$CHANNEL" "phase-remediate started" --as "$TICKET" --type info \
    --orch "$ORCH_ID" >/dev/null 2>&1 || true
fi

# 2. Start a catalyst-session for cost/token instrumentation.
SESSION_SCRIPT="${PLUGIN_ROOT}/scripts/catalyst-session.sh"
if [[ -x "$SESSION_SCRIPT" ]]; then
  CATALYST_SESSION_ID=$("$SESSION_SCRIPT" start \
    --skill "phase-remediate" \
    --ticket "$TICKET" \
    --workflow "${CATALYST_SESSION_ID:-}")
  export CATALYST_SESSION_ID
fi

# 3. Mark the signal file as running + persist catalystSessionId (CTL-496:
#    orchestrate-roll-usage --phase reads this to attribute cost).
TS=$(date -u +%Y-%m-%dT%H:%M:%SZ)
TMP="${SIGNAL_FILE}.tmp.$$"
jq --arg ts "$TS" --arg sid "${CATALYST_SESSION_ID:-}" '
  .status = "running"
  | .updatedAt = $ts
  | if $sid != "" then .catalystSessionId = $sid else . end
' "$SIGNAL_FILE" > "$TMP" \
  && mv "$TMP" "$SIGNAL_FILE"

# CTL-587: test-kill after-prelude. Exits AFTER the signal is flipped to running
# but BEFORE any commit work, so reclaimDeadWorkIfPossible's remediate-probe
# returns false on the next staleness tick and the revive path engages. Mode
# suffix `${PHASE}:after-prelude` keeps the env var phase-agnostic.
if [[ "${CATALYST_TEST_KILL_PHASE:-}" == "${PHASE}:after-prelude" ]]; then
  echo "[CTL-587 test-kill] aborting after prelude" >&2
  exit 137
fi

# 4. Locate verify.json — the fix brief. The dispatcher already gated on its
#    existence; we re-read to extract the findings + regression_risk.
VERIFY_ARTIFACT="${ORCH_DIR}/workers/${TICKET}/verify.json"
[[ -f "$VERIFY_ARTIFACT" ]] || { echo "phase-remediate: verify.json missing for ${TICKET}" >&2; exit 1; }
REGRESSION_RISK="$(jq -r '.regression_risk // 0' "$VERIFY_ARTIFACT")"
HIGH_COUNT="$(jq -r '[.findings[]? | select(.severity == "high")] | length' "$VERIFY_ARTIFACT")"
echo "phase-remediate: verify.json = ${VERIFY_ARTIFACT} (regression_risk=${REGRESSION_RISK}, high findings=${HIGH_COUNT})"
jq -r '.findings[]? | "- [\(.severity)] \(.kind) \(.file // "?"):\(.line // "?") — \(.message)\n    fix: \(.recommendation // "(none)")"' "$VERIFY_ARTIFACT" || true

# 5. Linear status is written by the coordinator (CTL-558): the execution-core
#    scheduler applies the `remediating` → Remediate state when it dispatches
#    this phase. The phase agent no longer transitions Linear itself.

/goal condition

Transcript-evaluable so a /goal evaluator (which only sees Claude's text output, not the filesystem) can decide pass/fail from what the agent prints.

/goal "I have read verify.json's findings[] and addressed every severity:high
       finding (plus the lower-severity regression_risk drivers I can fix
       deterministically), committed the remediation so `git diff <base>..HEAD`
       includes my new fix commit, and printed the commit subject + a targeted
       gate (tsc/test/lint on the touched files) showing `exit 0` to my
       transcript. The router re-dispatches `verify` to re-check the whole
       diff (CTL-653) — I do NOT re-run the full verify suite myself.
       (Linear status is written by the coordinator — CTL-558 — not this agent.)"

Phase-specific work

Remediate is fix-capable and reads verify.json.findings[] as its brief. There is no canonical wrapper — do the fix work here:

  1. Triage the findings. Order by severity (every severity:"high" is

must-fix) and by kind (type / test / lint / security / reward-hacking are deterministic; review / coverage / silent-failure may need judgment). Each finding carries file, line, message, and a recommendation — that recommendation is what phase-verify asks for.

  1. Apply the fixes via Edit/Write directly on the named files. Stay scoped

to what the findings call out — phase-remediate is a fix pass, not a redesign. If a finding is a false positive or already addressed on HEAD, note it in the transcript and skip it (do not fabricate a change to satisfy it).

  1. Re-run the targeted gates fo
Compartilhar X LinkedIn