---
name: skill-task-health
type: skill
description: >-
  Verify the scheduled layer is healthy on two axes — behaviour (each scheduled
  task still produces its expected observable output) and deployment parity
  (every canon task/routine artefact has a live, enabled schedule, and every
  live schedule maps back to a canon artefact). Use when running the task-health
  check, or when asked whether the scheduled tasks are still doing what their
  canon says, or whether everything that should be scheduled actually is. Keeps a
  small registry of task → expected output → cadence, confirms each happened in
  its window, reconciles the canon task-set against the live schedule list, and
  flags gaps via skill-issue-capture. Propose-only — never restarts or edits a
  task. Owned by Pulse; sibling to skill-ops-sync (artefact text parity) — this
  checks behaviour and wiring, not text.
---

# task-health

A health check for the scheduled layer. `skill-ops-sync` confirms a task's *text* matches between Claude canon and the repo; this confirms the deployed task still *does* what that text describes, **and** that everything which should be deployed actually is. Three things are independent and each fails silently: text can be in parity while behaviour has regressed; behaviour can be fine on the tasks that exist while a canon task was never wired at all; and a stale schedule can linger with no canon artefact behind it. This skill checks the latter two — behaviour and deployment parity. Propose-only: it flags a gap, never restarts, edits, or wires anything.

## Trigger

Scheduled (Pulse), daily or on the ops cadence; or on demand ("are the scheduled tasks still working?", "is everything that should be scheduled actually scheduled?"). Linear connector, the scheduled-tasks list, plus read access to whatever surface a checked task writes to.

## Behaviour

### Pass A — Behaviour (does each task still do its job)

1. **Read the registry** — the small set of scheduled tasks that have a *clear, observable* output, each with its expected output and a cadence window. Only tasks with an unambiguous signal belong here; verifying everything is explicitly not the goal.
2. **Check the signal fired** — for each task, confirm its expected output appears within its window.
3. **Rule out a legitimate empty first.** Some tasks act only when there is input (e.g. a sweep on an empty inbox); doing nothing is then *healthy*. Distinguish "no output because there was nothing to do" from "no output because the task regressed" — check that the task **ran at all** (its last-run marker / run log) before treating a missing output as a regression. A task that ran and correctly produced nothing is green.
4. **Flag a confirmed regression** — via `skill-issue-capture` (a Backlog ticket in Apps / os.Claude), naming the task, the expected output, and when it was last seen. One flag per regressed task; dedupe against any open flag.

### Pass B — Deployment parity (is everything wired, and nothing orphaned)

5. **List both sides.** Enumerate the **canon** scheduled artefacts — every `task-*` and `routine-*` in the skills store — and the **live** deployments: the Cowork scheduled tasks (via the scheduled-tasks list) and the Cloud Routines (Claude Code surface). A `skill-*` that has a canon `task-*`/`routine-*` loader is represented by that loader; a skill with no scheduled artefact and no live schedule is not in scope for this pass.
6. **Reconcile, both directions.**
   - **Missing deployment** — a canon `task-*`/`routine-*` artefact with *no* live, enabled schedule (or one that is disabled). This is the gap that let a saved artefact never actually run (worked case: `task-bara-operator-loop` and `skill-task-health` both existed as canon with no schedule until 2026-07-01).
   - **Orphan schedule** — a live scheduled task/routine with *no* matching canon artefact, or pointing at a skill that no longer exists (cf. the `skill-delivery-loop` orphan, 2026-06-23).
   - **Loader drift** — a live config whose loader line does not point at the artefact it claims to run (a stale inlined prompt instead of the one-line loader).
7. **Flag each gap** — via `skill-issue-capture`, one flag per gap, naming the artefact and the side it is missing from. A missing deployment is a wiring proposal for the operator (the schedule is the operator's to create); an orphan is a cleanup proposal. Never wire, disable, or edit a schedule — that is the operator's call.

8. **Report** — a short health summary: behaviour (tasks checked, green, flagged), parity (canon vs live counts, missing deployments, orphans, loader drift), each with its issue link.

## The registry (Pass A)

Maintained here as tasks gain a clear signal — seed set:

| Scheduled task | Expected observable output | Window |
| -- | -- | -- |
| `task-daily-report` | An initiative status update posted to each of the four team-mirror initiatives | last 24–48h |
| `task-pipeline-sweep` | New Pipeline issues captured from intake, **or** a recorded "no inbound" note | its schedule interval |
| `task-ops-sync` | A parity report produced (publish tickets raised or an explicit in-sync result) | its schedule interval |
| `task-pulse-retro` | Friction queue drained — artefacts produced, or an explicit empty-queue result | its schedule interval |
| `task-bara-operator-loop` | A weekly BARA loop status posted (progress vs proof points), or a recorded no-op | weekly |

Add a row only when a task has an output you can check without ambiguity; leave a task off rather than invent a signal for it.

## Guardrails

- **Propose-only** — flag, never restart, never edit a task or its config, never wire, disable, or re-enable a schedule.
- **Clear signals only (Pass A)** — never invent an expected output or chase a task whose success isn't observable.
- **No false alarms** — rule out a legitimate empty (task ran, nothing to do) before flagging; a missing run and a missing output are different findings.
- **Parity both directions (Pass B)** — a canon artefact with no schedule and a schedule with no canon artefact are both findings; a freshly-saved artefact awaiting its first wiring is a missing-deployment flag, not a regression.
- **One flag per gap**, deduped against any existing open flag.

## Setup

- Deployed as a **Cowork scheduled task** (`task-health`, cloud), Pulse-owned.
- **Connectors:** Linear, the scheduled-tasks list, plus read access to each checked task's output surface.
- **Cadence:** daily, or aligned with the ops sweep.
- **Loader:** `Read .claude/skills/skill-task-health/SKILL.md and follow it verbatim.`

On finish, run skill-ops-retro capture on this run's friction: file a FRICTION note to the Pulse queue for the drain pass to assess.
