Skip to content

Watcher: 24/7 self-paced campaign loop that re-feeds goals, pulls metrics, and reacts to events #72

Description

@wesleysimplicio

Parent epic: #64

Goal

Port the simplicio-tasks watch lane + hooks/loop_stop.py re-feed pattern: a 24/7 watcher that keeps a campaign loop alive — re-feeding the frozen campaign goal (#65 anchor) each cycle, pulling metrics, reacting to events, and pacing itself via the host scheduler instead of busy-polling.

Cycle (each wake)

  1. doctor --json (Doctor: preflight that verifies env, toolchains, and adapter reachability — BLOCKS, never fake-passes #71) — skip cycle to blocked state if preflight fails.
  2. anchor check (Anchor: freeze campaign/piece acceptance criteria at intake and gate "done" on verified AC #65) — re-read the frozen goal; abort any drifted in-flight work.
  3. Harvest: pull metrics for published pieces (analytics lane Analytics: score organic performance across social, Reddit, forums, and dev portals #54), ingest new comments/replies (Community loop: monitor comments and draft respectful technical replies #60 queue), check scheduled pieces due.
  4. Decide: consult journal (Journal: durable run-journal + stall detector so the loop switches strategy instead of oscillating #66) for stalled pieces → strategy switch; winners → promote lane (Paid growth: promote organic winners into paused ad drafts with budget guardrails #55, paused drafts only); losers → learning entry.
  5. Act through gates: every transition passes the evidence gate (Evidence gate: piece completion only on typed promise backed by artifacts, never a bare claim #67) and action gate (Action gate: fail-closed hook blocking live publish, ad activation, and spend without a logged promotion record #69).
  6. Journal the cycle and schedule the next wake (self-paced: shorter when pieces are in flight, longer when idle; hard cap on cycles per day).

Guardrails

  • The watcher never escalates its own permissions: DRY_RUN posture and human-approval requirements are identical to interactive runs.
  • Stall behavior: N consecutive no-progress cycles → single summarized escalation to human, then back off — no alert spam.
  • Every cycle appends to data/runs.jsonl with cycle id, actions taken, tokens/cost estimate.

Acceptance criteria

  • E2E test (mocked clock + mocked adapters): a full wake cycle runs all 6 steps and schedules the next wake.
  • E2E test: doctor failure → cycle logs blocked and does NOT touch pieces.
  • Cycle cap and back-off are configurable via env and enforced.
  • Runtime-agnostic: pacing binds to the host scheduler where available (Claude scheduler, cron, launchd/systemd via lib/schedule/*), with a documented manual fallback.

Metadata

Metadata

Assignees

No one assigned

    Projects

    Status
    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions