marketing-loops · loop-state

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
}

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

Idempotency patterns

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:

Resetting & backfilling safely


Source: https://github.com/coreyhaines31/marketingskills/skills/marketing-loops/references/loop-state.md · v1.2.0 · MIT License (c) 2025 Corey Haines.