All skills
coreyhaines31 avatar

/marketing-loops

@003db09

When the user wants to set up a recurring, self-running marketing workflow — a repeatable loop an AI agent runs on a cadence (weekly, daily, on a trigger) rather than a one-off task. Also use when the user mentions 'marketing loop,' 'recurring marketing workflow,' 'automate my marketing,' 'marketing on autopilot,' 'weekly marketing review,' 'ad fatigue check,' 'content refresh loop,' 'churn watch,' 'ranking drop alert,' 'always-on marketing,' 'marketing automation workflow,' or 'run this every week.' Use this to pick, adapt, and schedule an ongoing marketing loop that orchestrates the other marketing skills. For one-off marketing ideas, see marketing-ideas. For the experimentation loop specifically, see ab-testing.

Use this Skill: https://skilld.dev/gh/coreyhaines31/marketingskills/marketing-loops

This session only. Nothing lands on disk.

referencesloop-state.md

≈955 tokens on demand. Your agent reads this file only when SKILL.md points to it.

Loop State & Run Logging

Idempotency is only real if the loop can remember what it already did between runs. This reference defines where that state lives and how to log runs — so loops don't double-act, re-nag the same people, or re-alert the same issue.

Where state lives

Persist each loop's state in a file under .agents/loops/ — the same .agents/ convention this repo uses for product-marketing.md and listening-sources.md. One state file per loop:

.agents/loops/<loop-name>.json     # the loop's memory
.agents/loops/<loop-name>.log      # append-only run log

If your scheduler or platform provides its own dedupe/cursor storage, use that instead — the point is durable state, not the specific file. Never keep state only in memory; a loop that forgets on restart will repeat itself.

What to store

A state file holds whatever the loop needs to not repeat itself:

{
  "loop": "churn-signal",
  "last_run": "2026-07-01T09:00:00Z",
  "cursor": "2026-06-30T23:59:59Z",        // watermark — only process items newer than this
  "handled": ["acct_1042", "acct_1077"],    // dedupe keys already acted on
  "cooldowns": {                             // entity -> next-eligible timestamp
    "acct_1042": "2026-07-15T00:00:00Z"
  },
  "in_flight": ["exp_pricing_v3"],           // actions/tests currently open
  "counters": { "acct_1042_attempts": 2 }    // e.g. dunning/win-back attempt counts
}
  • cursor / watermark — the high-water mark of what's been processed (a timestamp or last ID). The loop only looks at items past it.
  • handled — dedupe keys for items already acted on, so re-runs skip them.
  • cooldowns — per-entity suppression windows so you never re-contact someone inside the window.
  • in_flight — open items (running tests, active interventions) so the loop doesn't start a conflicting one.
  • counters — attempt counts that drive stop conditions (e.g., "after 2 win-back emails, stop").

Keep state small and prune it: expire old handled/cooldown entries once they're past their window.

Idempotency patterns

  • Watermark: process only items newer than cursor; advance cursor at the end of a successful run. Safe to re-run — it won't reprocess.
  • Dedupe set: before acting on an item, check its key against handled; add it after acting.
  • Cooldown map: before contacting an entity, check cooldowns[entity]; set it after contact.
  • In-flight guard: before starting an action that shouldn't overlap (a test, an intervention), check in_flight.

Run logging

Append one line per run, whether or not it acted. This is the audit trail and the vanity-loop detector.

2026-07-01T09:00Z  checked=312  acted=2   note="2 accounts newly at-risk, interventions staged"
2026-07-02T09:00Z  checked=298  acted=0   note="no action"
2026-07-03T09:00Z  checked=305  acted=0   note="no action"

Log at minimum: timestamp, how many items checked, how many acted on, and a short note. Use it to answer two questions:

  • Is it a vanity loop? If every run is acted=0 for weeks and nobody misses it — or it acts every run (a sign it's chasing noise) — reconsider it.
  • Did it double-act? Two runs acting on the same entity means the dedupe/cooldown state isn't working.

Resetting & backfilling safely

  • To reset a loop, clear its cursor/handled — but keep cooldowns so a reset doesn't spam people who were recently contacted.
  • On first run (no state yet), set the watermark to "now" rather than processing all history, or you'll blast every historical item. If you genuinely want a backfill, do a dry run first (log what it would do, act on nothing) and respect cooldowns.
  • Never log raw PII in state or run logs — use IDs or hashes (see loop-guardrails.md).

Source: SKILL.md on GitHub

No alerts2mo3 checks · Risk SAFE
  • Gen Agent Trust Hub2mo

    The skill provides a structured framework for marketing automation loops with a focus on repeatable systems and safety guardrails. It establishes a vulnerability surface for indirect prompt injection by ingesting external data from social media and news sources, though it explicitly requires human approval for all outbound actions to mitigate this risk.

  • Socket2mo

    No alerts

  • Snyk2mo

    Risk: LOW · No issues

Signed by skilld at 003db09. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub just now.

Activeupdated 3 months ago
metadata
{
  "version": "1.2.0"
}

README badge

README badge for coreyhaines31/marketingskills/marketing-loops