{
  "status": "follow_event_reaction_router_review_only_closed_until_human_yes",
  "created_utc": "2026-05-06T08:11:08Z",
  "canonical_namespace": "Sonic-Forage",
  "purpose": "Define what happens when somebody follows/subscribes: safe visual/audio/lore reactions first; platform API wiring later only after exact approval and rotated credentials.",
  "review_only": true,
  "requires_human_approval": true,
  "auto_stream_enabled": false,
  "auto_platform_api_enabled": false,
  "auto_chat_post_enabled": false,
  "auto_obs_control_enabled": false,
  "auto_reward_fulfillment_enabled": false,
  "auto_payment_enabled": false,
  "auto_dm_enabled": false,
  "secret_required_for_live_events": true,
  "live_event_sources": [
    {
      "source": "manual_operator_button",
      "status": "ready_now",
      "notes": "Operator can trigger the OBS browser-source URL or simulator without platform credentials."
    },
    {
      "source": "Kick/Twitch/EventSub/webhook",
      "status": "planned_closed",
      "notes": "Requires official event source, webhook signing, rate limits, and rotated credentials before live use."
    },
    {
      "source": "chat_command_simulation",
      "status": "review_only",
      "notes": "May simulate a follow for rehearsal; must not claim a real follower event."
    }
  ],
  "on_follow_sequence": [
    {
      "t": "0s",
      "effect": "flash neon lower-third: NEW SIGNAL DETECTED"
    },
    {
      "t": "1s",
      "effect": "show follower handle if allowed; otherwise show anonymous Signal Scout"
    },
    {
      "t": "3s",
      "effect": "unlock next signal phrase and write to manual queue"
    },
    {
      "t": "6s",
      "effect": "invite safe chat prompt: type one word for the next transmission"
    },
    {
      "t": "10s",
      "effect": "fade back to proof hub ticker"
    }
  ],
  "on_subscribe_sequence": [
    {
      "t": "0s",
      "effect": "Signal Keeper badge animation"
    },
    {
      "t": "2s",
      "effect": "supporter lore roll, opt-in only"
    },
    {
      "t": "5s",
      "effect": "queue one public proof drop idea for manual approval"
    },
    {
      "t": "10s",
      "effect": "display no financial promises / no private paywall claims"
    }
  ],
  "action_registry": [
    {
      "intent": "follow_alert_visual",
      "risk": "low",
      "allowed_now": true,
      "requires_confirmation": false,
      "target": "OBS browser source URL/manual simulator"
    },
    {
      "intent": "unlock_signal_phrase",
      "risk": "low",
      "allowed_now": true,
      "requires_confirmation": false,
      "target": "local manifest/manual queue"
    },
    {
      "intent": "thank_viewer_in_chat",
      "risk": "medium",
      "allowed_now": false,
      "requires_confirmation": true,
      "target": "platform chat API"
    },
    {
      "intent": "change_stream_title",
      "risk": "medium",
      "allowed_now": false,
      "requires_confirmation": true,
      "target": "platform dashboard/API"
    },
    {
      "intent": "grant_paid_reward",
      "risk": "high",
      "allowed_now": false,
      "requires_confirmation": true,
      "target": "platform/payment systems"
    },
    {
      "intent": "dm_viewer",
      "risk": "high",
      "allowed_now": false,
      "requires_confirmation": true,
      "target": "platform DM"
    }
  ],
  "sample_events": [
    {
      "type": "follow",
      "display_name": "Signal Scout",
      "phrase": "THE CROWD UNLOCKED THE NEXT TRANSMISSION"
    },
    {
      "type": "sub",
      "display_name": "Signal Keeper",
      "phrase": "THE FORGE GOT MORE FUEL"
    },
    {
      "type": "raid",
      "display_name": "Incoming Caravan",
      "phrase": "A NEW CREW ENTERED THE AFTERPARTY"
    }
  ],
  "closed_gates": {
    "platform_api": false,
    "real_event_webhook": false,
    "chat_write": false,
    "obs_websocket_control": false,
    "payment_or_rewards": false,
    "dm_or_outreach": false,
    "public_claim_real_event": false,
    "secret_exposure": false
  },
  "approval_phrase": "Approve live follower event wiring: platform=<Kick/Twitch>, event_source=<official API/webhook>, action=<visual only/chat thank/etc>, credential_status=<rotated/safe env>, test_scope=<dry-run/live>, time=<now/scheduled>",
  "proof_paths": [
    "docs/growth/follow-event-reactions.html",
    "docs/data/follow-event-reaction-router.json",
    "docs/streaming/obs/follow_event_overlay.html"
  ]
}