emo-social-insta-dm-agent/docs/external_review/external_llm_review_packet_public_v2.md

37 KiB
Raw Export PDF Blame History

External Review Packet (Public) v2 — emo-social + Instagram DM Draft Assistant

Last updated: 2025-12-25
Audience: external reviewers (human or LLM)
Purpose: solicit critical feedback (not praise) on the end-to-end design + governance stack.

Public-safety note: this packet contains no private DM transcripts, no personal identities, and no secrets/tokens. It uses aggregated counts and “made-for-review” draft examples only.


0) First: what you must do (reviewer instructions)

  1. Read this packet end-to-end.
  2. Answer the questions in Section 6 exactly.
  3. Be blunt. Do not flatter. If something is weak, say so plainly and propose a fix.

0.1 Your first line (required)

State:

  • Model/provider (as accurately as you can)
  • Knowledge cutoff (date or best estimate)
  • Whether you could access this URL content directly: Yes/No

If you cannot access URLs, say so and stop (do not hallucinate the dossier).


1) What this is (plain English)

This is a clinically supervised research stress-test for emo-social.infrafabric.io, prepared as part of an Anthropic Fellowship application. It is not a commercial product.

In parallel, we are building a separate component: an Instagram DM draft assistant for the Instagram account @socialmediatorr. The DM assistant is not therapy, and it must never handle crisis content. Its job is to reduce delays on repetitive inbox questions while keeping trust intact.

1.1 Quick glossary (so you dont get stuck on our internal names)

You do not need to know any InfraFabric terminology to review this.

  • Draft assistant: the system writes a suggested reply, but does not send it.
  • Triage: the first sorting step (safe to draft vs needs a human vs urgent).
  • Panel: a checklist-style review of the draft (multiple “seats” that vote).
  • Trace / evidence bundle: an audit log of what happened, so we can prove decisions later without publishing private DMs.
  • IF.GOV.TRIAGE / IF.GOV.PANEL / IF.TTT: these are just our internal labels for the three items above. If the names annoy you, ignore them and focus on the behavior.

2) What we are building (two parts)

2.1 emo-social.infrafabric.io (research system)

Purpose: help users think more clearly about emotions using a defined “Sergio” style (direct, concrete, anti-vague) with a strict rule: reply in the users language.

What it is not:

  • Not a medical device.
  • Not a replacement for professional care.
  • Not a crisis service.

2.2 Instagram DM draft assistant for @socialmediatorr

Purpose: produce draft replies for incoming Instagram DMs, in the users language, aligned with Sergios concise DM style. A human can review/edit before sending.

What it is not:

  • Not ManyChat broadcast automation.
  • Not an auto-messaging spam tool.
  • Not therapy-by-DM.
  • Not allowed to respond to self-harm / crisis situations.

3) The constraint: we must simulate debates (no paid external APIs)

We want to use the InfraFabric governance primitives as a proof-of-concept on this low-stakes DM assistant.

However: we currently do not have funds for paid external LLM API access. So “multi-voice debate” must be simulated using:

  • deterministic rule-based seats (Safety, Boundary, Language, Privacy, Next-step, etc.)
  • optional local models only (if available), but nothing that requires paid external calls

Your job as reviewer: tell us if this simulation is still a meaningful governance POC, and how to make it credible without external APIs.


4) What the data shows (aggregated, no identities)

Inbox: @socialmediatorr
Time zone used here: CET
Observed window: 2024-10-20 → 2025-12-22 (429 days)

4.1 Basic counts

Metric Value
Total messages 54,069
Messages sent by owner 43,607
Messages sent by others 10,462
Messages that look like a question/request 2,715
System “new follower” messages 8,081

Important caveat: the dataset is not evenly distributed. 202512 dominates (87.5% of messages). Treat “trend claims” with caution.

4.2 Top intents (questions/requests)

The inbox is dominated by repeated intents (good for templating):

Rank Topic (plain English) Count Share of questions/requests
1 Just one word: book 1,857 68.4%
2 What is this? 203 7.5%
3 Can you send the video? 189 7.0%
4 Other question 118 4.3%
5 Can you help me? 74 2.7%

4.3 Distress / escalation prevalence (so we dont overreact)

We ran a strict keyword scan on inbound text messages (subset of inbound total):

  • Inbound text messages scanned: 10,337
  • High-risk flags found: 9 messages total (0.087%, ~1 in 1,150), across 9 threads
    • 3 with explicit self-harm/suicide wording
    • 6 with abuse/maltreatment wording

This is a lower bound (euphemisms wont match), but it indicates explicit crisis wording is rare in this inbox.


5) The proposed governance implementation (IF.GOV + IF.TTT)

We propose implementing the DM assistant as an auditable governance pipeline:

  • Triage step (IF.GOV.TRIAGE): decides risk + route (normal vs needs-human vs urgent) and detects language + topic.
  • Review panel step (IF.GOV.PANEL): runs a set of rule-based “seats” that approve, request changes, or veto (no external APIs required).
  • Trace record (IF.TTT): stores an audit record (hashes + decisions + evidence bundle) so results are provable later without publishing private DMs.

Key design choice: draft-only by default. No automated sending until proven safe.

5.1 What “panel debate” means without external APIs

The “panel” is a set of deterministic evaluators (“seats”). Each seat produces:

  • a vote (approve, request_changes, veto)
  • reasons
  • patch suggestions (structured operations)

Aggregation is deterministic:

  • Any veto → escalate to human (or urgent escalate).
  • Any request_changes → apply patches, re-run seats once.
  • Else approve.

5.2 Where this lives (reference, not required for the review)

Spec file (included below): IF.GOV + IF.TTT Spec — Instagram DM Draft Assistant


6) What we want from you (the review request)

6.1 Your understanding (58 lines)

Summarize what you think we are building and what the constraints are.

6.2 What looks strong (short list)

List only what is actually strong and why (no generic praise).

6.3 Debug the design: gaps / risks (ranked by severity)

Identify gaps we may have missed across:

  • safety (crisis, abuse, coercion, self-harm, harassment)
  • psychological harm (wrong tone, inviting disclosure, boundary confusion)
  • privacy (what gets stored, retention, de-identification failures)
  • UX (reviewer fatigue, slow workflows, low adoption)
  • engineering failure modes (token expiry, rate limiting, silent failures)

Rank by severity and explain why.

6.4 Patches to consider (concrete)

For each patch:

  • Describe the change in 13 sentences.
  • Explain the reason in 1 sentence.
  • If its a prompt or template change, show the exact edit (copy/paste).
  • If its a process change, name the exact step you add/remove.

6.5 Xmultiplier (make it 10× better)

Propose improvements under two constraints:

A) No paid external APIs (must be local + deterministic)

  • What would make this 10× more credible as a governance POC?
  • What would make it 10× more useful in a real inbox?

B) If budget later exists

  • What additional seats, tests, or review processes would you add?
  • What would you never outsource to an external model?

6.6 A safe test plan (step-by-step)

Propose a small test plan that:

  • starts in draft-only mode
  • uses a simple scoring rubric (correct language, correct intent, clear next step, no overreach)
  • measures false positives/false negatives on escalation routing
  • prevents “we fooled ourselves” success

6.7 Transferability (other verticals)

Could this governance pattern transfer to other contexts (support, sales, onboarding)?

  • What transfers unchanged?
  • What must be rebuilt from scratch?
  • Where does it become unsafe?

6.8 Five clarifying questions (exactly 5)

Ask the 5 questions that would most improve your review.


Appendix A — VoiceDNA (safe; no private DM quotes)

This VoiceDNA is derived from the last 6 months of manual (non-template) DM replies and contains rules + aggregate stats, not quotes.

{
  "schema_version": "voice_dna/v1",
  "created_at_utc": "2025-12-24T12:08:24+00:00",
  "subject": {
    "account": "@socialmediatorr",
    "owner_name": "Sergio de Vocht",
    "scope": "Instagram DMs"
  },
  "source": {
    "type": "instagram_export",
    "window": {
      "months": 6,
      "start_utc": "2025-06-24T12:08:20+00:00",
      "end_utc": "2025-12-24T12:08:20+00:00",
      "response_window_hours": 72.0
    },
    "classification": {
      "manual_reply_definition": "owner text message within response_window_hours of the most recent inbound message, excluding repeated templates",
      "scripted_template_definition": "owner canonicalized text sent >= 50 times across full export",
      "system_messages_excluded": [
        "you messaged <user> because they followed your account"
      ]
    },
    "scan": {
      "export_root_hint": "socialmediatorr-ig-export-raw-20251224",
      "scanned_conversations": 10100,
      "scanned_message_files": 10061,
      "candidate_responses_in_window": 18934,
      "manual_responses_in_window": 825,
      "scripted_template_count": 24
    }
  },
  "policies": {
    "language": {
      "mode": "mirror_user_input_language",
      "supported_languages": [
        "English",
        "Spanish",
        "French",
        "Catalan"
      ],
      "rules": [
        "Reply in the same language as the user's most recent message that contains enough text to classify.",
        "Do not translate the user's message unless they explicitly ask for a translation.",
        "Do not mix languages inside a single reply unless the user mixes languages first.",
        "If the user's message is too short to classify, reuse the last confidently detected language in the same thread.",
        "If there is still no signal, ask a 1-line clarification asking which language they prefer (keep it short)."
      ]
    }
  },
  "language_observed": {
    "inbound_last_window_counts": {
      "English": 2828,
      "Too short to tell": 5024,
      "Spanish": 2176,
      "French": 191,
      "Catalan": 16
    },
    "manual_reply_counts": {
      "Spanish": 541,
      "Too short to tell": 255,
      "English": 17,
      "French": 1,
      "Catalan": 11
    }
  },
  "style": {
    "manual_replies": {
      "overall": {
        "count": 825,
        "length": {
          "chars": {
            "min": 2,
            "p10": 13,
            "median": 54,
            "p90": 199,
            "max": 928,
            "mean": 87.47878787878788
          },
          "words": {
            "min": 1,
            "p10": 2,
            "median": 11,
            "p90": 34,
            "max": 169,
            "mean": 15.436363636363636
          }
        },
        "rates": {
          "emoji_messages_pct": 16.363636363636363,
          "question_messages_pct": 32.484848484848484,
          "ends_with_question_pct": 27.151515151515156,
          "exclamation_messages_pct": 18.303030303030305,
          "linebreak_messages_pct": 9.212121212121211,
          "url_messages_pct": 4.121212121212121,
          "handle_messages_pct": 0.0,
          "number_messages_pct": 9.454545454545455,
          "starts_with_greeting_pct": 4.96969696969697,
          "contains_thanks_pct": 4.484848484848484,
          "contains_cta_terms_pct": 4.848484848484849
        },
        "top_emojis": [
          {
            "emoji": "🙌",
            "count": 41
          },
          {
            "emoji": "🫶",
            "count": 23
          },
          {
            "emoji": "👋",
            "count": 19
          },
          {
            "emoji": "🎁",
            "count": 17
          },
          {
            "emoji": "💪",
            "count": 14
          },
          {
            "emoji": "👇",
            "count": 12
          },
          {
            "emoji": "😜",
            "count": 7
          },
          {
            "emoji": "😉",
            "count": 4
          },
          {
            "emoji": "🤣",
            "count": 2
          },
          {
            "emoji": "🙏",
            "count": 2
          },
          {
            "emoji": "⬆",
            "count": 2
          },
          {
            "emoji": "👀",
            "count": 2
          },
          {
            "emoji": "¦",
            "count": 1
          },
          {
            "emoji": "😅",
            "count": 1
          },
          {
            "emoji": "🤝",
            "count": 1
          },
          {
            "emoji": "☺",
            "count": 1
          },
          {
            "emoji": "🫡",
            "count": 1
          },
          {
            "emoji": "😁",
            "count": 1
          },
          {
            "emoji": "👌",
            "count": 1
          },
          {
            "emoji": "🚀",
            "count": 1
          }
        ]
      },
      "by_language": {
        "Spanish": {
          "count": 541,
          "length": {
            "chars": {
              "min": 5,
              "p10": 35,
              "median": 99,
              "p90": 211,
              "max": 928,
              "mean": 116.06469500924214
            },
            "words": {
              "min": 1,
              "p10": 6,
              "median": 18,
              "p90": 38,
              "max": 169,
              "mean": 20.478743068391868
            }
          },
          "rates": {
            "emoji_messages_pct": 20.70240295748614,
            "question_messages_pct": 39.55637707948244,
            "ends_with_question_pct": 32.34750462107209,
            "exclamation_messages_pct": 16.266173752310536,
            "linebreak_messages_pct": 13.67837338262477,
            "url_messages_pct": 2.2181146025878005,
            "handle_messages_pct": 0.0,
            "number_messages_pct": 9.242144177449168,
            "starts_with_greeting_pct": 7.578558225508318,
            "contains_thanks_pct": 6.839186691312385,
            "contains_cta_terms_pct": 7.024029574861368
          },
          "top_emojis": [
            {
              "emoji": "🙌",
              "count": 24
            },
            {
              "emoji": "🫶",
              "count": 23
            },
            {
              "emoji": "👋",
              "count": 19
            },
            {
              "emoji": "🎁",
              "count": 17
            },
            {
              "emoji": "👇",
              "count": 12
            },
            {
              "emoji": "💪",
              "count": 10
            },
            {
              "emoji": "😜",
              "count": 7
            },
            {
              "emoji": "😉",
              "count": 4
            },
            {
              "emoji": "🤣",
              "count": 2
            },
            {
              "emoji": "🙏",
              "count": 2
            },
            {
              "emoji": "⬆",
              "count": 2
            },
            {
              "emoji": "👀",
              "count": 2
            },
            {
              "emoji": "😅",
              "count": 1
            },
            {
              "emoji": "🤝",
              "count": 1
            },
            {
              "emoji": "☺",
              "count": 1
            },
            {
              "emoji": "😁",
              "count": 1
            },
            {
              "emoji": "👌",
              "count": 1
            },
            {
              "emoji": "🚀",
              "count": 1
            },
            {
              "emoji": "⏱",
              "count": 1
            },
            {
              "emoji": "🫂",
              "count": 1
            }
          ]
        },
        "Too short to tell": {
          "count": 255,
          "length": {
            "chars": {
              "min": 2,
              "p10": 10,
              "median": 30,
              "p90": 53,
              "max": 151,
              "mean": 32.01176470588236
            },
            "words": {
              "min": 1,
              "p10": 1,
              "median": 4,
              "p90": 11,
              "max": 29,
              "mean": 5.749019607843137
            }
          },
          "rates": {
            "emoji_messages_pct": 7.8431372549019605,
            "question_messages_pct": 19.607843137254903,
            "ends_with_question_pct": 17.647058823529413,
            "exclamation_messages_pct": 23.52941176470588,
            "linebreak_messages_pct": 0.39215686274509803,
            "url_messages_pct": 4.705882352941177,
            "handle_messages_pct": 0.0,
            "number_messages_pct": 7.0588235294117645,
            "starts_with_greeting_pct": 0.0,
            "contains_thanks_pct": 0.0,
            "contains_cta_terms_pct": 0.0
          },
          "top_emojis": [
            {
              "emoji": "🙌",
              "count": 15
            },
            {
              "emoji": "💪",
              "count": 4
            },
            {
              "emoji": "🫡",
              "count": 1
            }
          ]
        },
        "English": {
          "count": 17,
          "length": {
            "chars": {
              "min": 4,
              "p10": 11,
              "median": 23,
              "p90": 38,
              "max": 40,
              "mean": 23.176470588235293
            },
            "words": {
              "min": 2,
              "p10": 3,
              "median": 4,
              "p90": 6,
              "max": 8,
              "mean": 4.588235294117647
            }
          },
          "rates": {
            "emoji_messages_pct": 11.76470588235294,
            "question_messages_pct": 23.52941176470588,
            "ends_with_question_pct": 23.52941176470588,
            "exclamation_messages_pct": 17.647058823529413,
            "linebreak_messages_pct": 0.0,
            "url_messages_pct": 0.0,
            "handle_messages_pct": 0.0,
            "number_messages_pct": 0.0,
            "starts_with_greeting_pct": 0.0,
            "contains_thanks_pct": 0.0,
            "contains_cta_terms_pct": 11.76470588235294
          },
          "top_emojis": [
            {
              "emoji": "🙌",
              "count": 2
            }
          ]
        },
        "French": {
          "count": 1,
          "length": {
            "chars": {
              "min": 29,
              "p10": 29,
              "median": 29,
              "p90": 29,
              "max": 29,
              "mean": 29.0
            },
            "words": {
              "min": 5,
              "p10": 5,
              "median": 5,
              "p90": 5,
              "max": 5,
              "mean": 5.0
            }
          },
          "rates": {
            "emoji_messages_pct": 100.0,
            "question_messages_pct": 0.0,
            "ends_with_question_pct": 0.0,
            "exclamation_messages_pct": 0.0,
            "linebreak_messages_pct": 0.0,
            "url_messages_pct": 0.0,
            "handle_messages_pct": 0.0,
            "number_messages_pct": 0.0,
            "starts_with_greeting_pct": 0.0,
            "contains_thanks_pct": 0.0,
            "contains_cta_terms_pct": 0.0
          },
          "top_emojis": [
            {
              "emoji": "¦",
              "count": 1
            }
          ]
        },
        "Catalan": {
          "count": 11,
          "length": {
            "chars": {
              "min": 26,
              "p10": 48,
              "median": 52,
              "p90": 99,
              "max": 205,
              "mean": 72.0909090909091
            },
            "words": {
              "min": 5,
              "p10": 5,
              "median": 8,
              "p90": 10,
              "max": 34,
              "mean": 9.727272727272727
            }
          },
          "rates": {
            "emoji_messages_pct": 0.0,
            "question_messages_pct": 0.0,
            "ends_with_question_pct": 0.0,
            "exclamation_messages_pct": 0.0,
            "linebreak_messages_pct": 9.090909090909092,
            "url_messages_pct": 90.9090909090909,
            "handle_messages_pct": 0.0,
            "number_messages_pct": 90.9090909090909,
            "starts_with_greeting_pct": 0.0,
            "contains_thanks_pct": 0.0,
            "contains_cta_terms_pct": 0.0
          },
          "top_emojis": []
        }
      }
    }
  }
}

Appendix B — Top 20 ready-made answers (multi-language; placeholders only)

These are draft replies for repeated intents. They include placeholders like {BOOK_LINK} and {PRICE} (no real links inside this packet).

Top 20 Ready-Made Answers (MultiLanguage)

VoiceDNA: voice_dna/voiceDNA_socialmediatorr_insta_dm.json

Rules:

  • Reply in the same language as the users message (English / Spanish / French / Catalan).
  • Replace {PLACEHOLDERS} before sending.
  • Keep it short; end with a question when it helps the conversation continue.

1) Just one word: book

  • English: Got it. Do you want the book link or the video first?
  • Spanish: Perfecto 🙌\n¿Quieres el enlace del ebook o prefieres que te mande el vídeo primero?
  • French: OK. Tu veux le lien du livre ou la vidéo dabord ?
  • Catalan: Perfecte. Vols lenllaç del llibre o el vídeo primer?

2) What is this?

  • English: Its a simple, practical resource to help you move forward. What are you looking for right now?
  • Spanish: Es un recurso práctico para avanzar.\n¿Qué estás buscando ahora mismo?
  • French: Cest un outil simple et pratique pour avancer. Tu cherches quoi en ce moment ?
  • Catalan: És un recurs simple i pràctic per avançar. Què busques ara mateix?

3) Can you send the video?

  • English: Sure — here it is: {VIDEO_LINK}. Want a quick summary first?
  • Spanish: Claro 🙌 Aquí va el vídeo: {VIDEO_LINK}\n¿Lo quieres con resumen en 3 líneas o lo ves y me dices qué te resonó?
  • French: Bien sûr. Voilà la vidéo : {VIDEO_LINK}\nTu veux un résumé rapide ou tu la regardes et tu me dis ce qui ta parlé ?
  • Catalan: Sí. Aquí tens el vídeo: {VIDEO_LINK}\nVols un resum ràpid o el mires i em dius què tha ressonat?

4) Other question

  • English: Tell me in one sentence what you need, and Ill point you to the right next step.
  • Spanish: Dime en 1 frase qué necesitas y te digo el siguiente paso 🙌
  • French: Dismoi en 1 phrase ce que tu veux, et je te dis la prochaine étape.
  • Catalan: Diguem en 1 frase què necessites i et dic el següent pas.

5) Can you help me?

  • English: Yes. What are you struggling with most right now?
  • Spanish: Sí.\n¿Qué es lo que más te está costando ahora mismo?
  • French: Oui. Questce qui est le plus difficile pour toi en ce moment ?
  • Catalan: Sí. Què és el que et costa més ara mateix?
  • English: Sure. Is this for the book or to book a call?
  • Spanish: Claro.\n¿El enlace es para el ebook o para reservar una llamada?
  • French: Bien sûr. Cest pour le livre ou pour réserver un appel ?
  • Catalan: Clar. És per al llibre o per reservar una trucada?

7) What does it cost?

  • English: Its {PRICE}. Want the link?
  • Spanish: Son {PRICE}.\n¿Te paso el enlace?
  • French: Cest {PRICE}. Tu veux le lien ?
  • Catalan: Són {PRICE}. Vols lenllaç?

8) Is this therapy?

  • English: No — this isnt therapy in DMs. I can share resources and options. What are you looking for?
  • Spanish: No, esto no es terapia por DM.\nPuedo ayudarte con recursos y opciones.\n¿Qué estás buscando?
  • French: Non, ce nest pas une thérapie en DM. Je peux te partager des ressources et des options. Tu cherches quoi ?
  • Catalan: No, això no és teràpia per DM. Puc compartir recursos i opcions. Què busques?

9) Where do I get the book?

  • English: Here you go: {BOOK_LINK}. Did it open for you?
  • Spanish: Aquí tienes el enlace: {BOOK_LINK}\n¿Te llega bien?
  • French: Tiens : {BOOK_LINK}. Ça souvre bien de ton côté ?
  • Catalan: Aquí ho tens: {BOOK_LINK}. Se tobre bé?

10) I cant find it / it didnt arrive

  • English: No worries — lets fix it. What email did you use to buy (or send a screenshot of the receipt)?
  • Spanish: Vale, lo solucionamos.\n¿Con qué email lo compraste? (o mándame una captura del recibo)
  • French: OK, on règle ça. Tu as acheté avec quel email ? (ou envoie une capture du reçu)
  • Catalan: Ho arreglem. Amb quin email ho vas comprar? (o envia una captura del rebut)

11) How do I book a call?

  • English: Book a call here: {CALENDLY_LINK}. What times work for you?
  • Spanish: Reserva aquí: {CALENDLY_LINK}\n¿Qué horarios te vienen bien?
  • French: Réserve ici : {CALENDLY_LINK}. Quels créneaux te vont ?
  • Catalan: Reserva aquí: {CALENDLY_LINK}. Quins horaris et van bé?

12) How do I start?

  • English: To start, tell me your goal in one sentence and Ill tell you the first step.
  • Spanish: Para empezar: dime tu objetivo en 1 frase y te digo el primer paso 🙌
  • French: Pour commencer, dismoi ton objectif en 1 phrase et je te donne le premier pas.
  • Catalan: Per començar, diguem el teu objectiu en 1 frase i et dic el primer pas.

13) Can we talk on WhatsApp?

  • English: We can. If you prefer WhatsApp: {WHATSAPP_LINK}. Want to continue there?
  • Spanish: Podemos.\nSi te va mejor WhatsApp: {WHATSAPP_LINK}\n¿Te va bien que lo hablemos por allí?
  • French: Oui. Si tu préfères WhatsApp : {WHATSAPP_LINK}. Ça te va de continuer làbas ?
  • Catalan: Sí. Si prefereixes WhatsApp: {WHATSAPP_LINK}. Et va bé seguir per allà?

14) How does it work?

  • English: Simple: you get the resource, apply it, and if you want we can go deeper. What do you want to improve?
  • Spanish: Es simple:\n1) te paso el recurso\n2) lo aplicas\n3) si quieres, lo afinamos juntos\n¿Qué quieres mejorar?
  • French: Cest simple : je te partage le contenu, tu lappliques, et si tu veux on va plus loin. Tu veux améliorer quoi ?
  • Catalan: És simple: et passo el recurs, lapliques, i si vols ho aprofundim. Què vols millorar?

15) What are the steps?

  • English: 1) Tell me what you want 2) I send the right link 3) You start. Whats your goal?
  • Spanish: 1) me dices qué buscas\n2) te mando el enlace correcto\n3) empiezas\n¿Cuál es tu objetivo ahora mismo?
  • French: 1) Tu me dis ce que tu veux 2) je tenvoie le bon lien 3) tu commences. Ton objectif, cest quoi ?
  • Catalan: 1) Em dius què busques 2) tenvio lenllaç correcte 3) comences. Quin és el teu objectiu?

16) Is this real?

  • English: Yes. If you want, Ill send the official link. What are you looking to get out of it?
  • Spanish: Sí, es real.\nSi quieres, te mando el enlace oficial.\n¿Qué estás buscando conseguir?
  • French: Oui, cest réel. Si tu veux je tenvoie le lien officiel. Tu veux obtenir quoi exactement ?
  • Catalan: Sí, és real. Si vols, tenvio lenllaç oficial. Què vols aconseguir exactament?

17) Is it free?

  • English: The full thing isnt free, but I can share a free starting point. Want it?
  • Spanish: No es gratis, pero sí tengo un punto de inicio gratuito.\n¿Quieres que te lo pase?
  • French: Ce nest pas gratuit, mais jai un point de départ gratuit. Tu veux que je te lenvoie ?
  • Catalan: No és gratis, però tinc un punt dinici gratuït. Vols que tel passi?

18) Can I get a refund?

  • English: Sure — happy to help. Send me the purchase email + date and Ill sort it.
  • Spanish: Claro, te ayudo.\nPásame el email de compra + la fecha y lo reviso.
  • French: Bien sûr. Envoiemoi lemail dachat + la date et je men occupe.
  • Catalan: És clar. Enviam lemail de compra + la data i ho gestiono.

19) How long does it take?

  • English: It depends, but usually {TIMEFRAME}. What are you trying to change?
  • Spanish: Depende, pero normalmente {TIMEFRAME}.\n¿Qué quieres cambiar tú?
  • French: Ça dépend, mais en général {TIMEFRAME}. Tu veux changer quoi, toi ?
  • Catalan: Depèn, però normalment {TIMEFRAME}. Què vols canviar tu?

20) Where are you based?

Note: added as a practical top20 coverage item.

  • English: Im based in {BASE_LOCATION} (CET) and I work online. Where are you based?
  • Spanish: Estoy en {BASE_LOCATION} (CET) y trabajo online.\n¿Tú dónde estás?
  • French: Je suis basé à {BASE_LOCATION} (CET) et je travaille en ligne. Et toi, tu es où ?
  • Catalan: Sóc a {BASE_LOCATION} (CET) i treballo online. I tu, on ets?

Appendix C — IF.GOV + IF.TTT spec (the proposed implementation)

IF.GOV + IF.TTT Spec — Instagram DM Draft Assistant (@socialmediatorr)

Status: proposal (POC)
Constraint: no paid external LLM APIs → “debates” are simulated using deterministic seats (rules) and optional local models only.

This spec describes how to implement the Instagram DM assistant as an auditable governance pipeline:

  • Triage step (IF.GOV.TRIAGE) decides risk + route (normal vs human vs urgent).
  • Review panel step (IF.GOV.PANEL) simulates a multiseat review of the proposed draft reply (no external APIs required).
  • Trace record (IF.TTT) records a chainofcustody (hashes + decisions + evidence bundle) so results are provable later.

0) System boundaries (what we will and wont do)

In scope

  • Ingest Meta webhook events for Instagram DMs.
  • Produce draft replies (default) using templates + simple intent routing.
  • Escalate a tiny fraction of DMs to a human (Sergio) quickly, with a direct “open thread” link.
  • Produce IF.TTTstyle trace records and evidence bundles for audit/replay.
  • Run “panel debates” without external APIs (rule seats + optional local model seats).

Out of scope (for the POC)

  • Automatic sending of replies to real clients (keep draft-only).
  • Therapy-by-DM, crisis intervention, diagnosis, or medical claims.
  • Storing/exporting full DM transcripts in a public repo.

1) High-level architecture

Components

  • Webhook receiver (already exists in production on emo-social.infrafabric.io): verifies Meta signature and normalizes events.
  • Event store: append-only storage of DM events + derived decisions (local, private).
  • Triage engine (IF.GOV.TRIAGE): risk + language + intent + confidence.
  • Draft engine: chooses a reply template (Top 20) or a safe fallback.
  • Panel engine (IF.GOV.PANEL): simulated debate across “seats” → approve/patch/escalate.
  • Trace recorder (IF.TTT): emits signed decision records + evidence bundles.
  • Reviewer UI: queue view for Drafts + Escalations + “open IG thread” action.

Data flow (valid Mermaid)

flowchart LR
  W[Meta webhook event] --> V[Verify signature]
  V --> N[Normalize event]
  N --> ES[Event store append]
  ES --> T[IF.GOV.TRIAGE]
  T -->|urgent| E[Escalation record]
  T -->|normal| D[Draft engine]
  T -->|needs-human| H[Human-required record]
  D --> P[IF.GOV.PANEL seats]
  P --> R[Panel decision]
  E --> TR[IF.TTT trace + bundle]
  H --> TR
  R --> TR
  TR --> UI[Reviewer UI queue]

2) IF.GOV.TRIAGE (no external API)

Inputs

  • sender_id (from webhook)
  • mid (message id)
  • timestamp_ms
  • text (if present; empty allowed)
  • minimal thread context (last N messages for this sender_id, if available)

Outputs (contract)

{
  "triage_version": "if.gov.triage/igdm/v1",
  "trace_id": "uuid",
  "ts_utc": "2025-12-25T12:00:00Z",
  "time_cet": "2025-12-25T13:00:00+01:00",
  "sender_id": "123",
  "mid": "m_abc",
  "language": { "code": "es", "confidence": 0.86, "source": "text_or_thread" },
  "intent": { "label": "book|link|video|price|help|other", "confidence": 0.90 },
  "risk": {
    "tier": "normal|needs-human|urgent",
    "score": 0.05,
    "reasons": ["..."],
    "panel_size": 5
  }
}

Triage rules (POC defaults)

  • Language detection
    • If message has enough text: detect language from message text.
    • Else: reuse last confident thread language.
    • Else: set confidence < 0.5 and prefer a 1line language question.
  • Intent detection
    • Keyword routing for: book, link, video, price/cost, call, therapy, etc.
    • If unknown: intent=other with low confidence.
  • Risk tier
    • urgent if self-harm/suicide signals OR violence/abuse indicators.
    • needs-human if: therapeutic disclosure, legal threats, harassment, complex personal crisis, repeated angry loop.
    • normal otherwise.

“Panel size” without external APIs

Panel size is computed deterministically from risk.score (same pattern as the existing guard_engine.py):

  • normal: 5 seats
  • needs-human: 10 seats (more checks, but still local)
  • urgent: 20 seats (but action is always escalate, not debate content)

3) Draft engine (no external API)

Principles

  • Use templates first, not a generative model.
  • Always mirror the users language (or ask a 1line language question if uncertain).
  • Keep replies short; ask one clear next question when helpful.
  • Never invite deep disclosure in DMs; route to “resources / call / book link”.

Draft outputs

{
  "draft_version": "igdm.draft/v1",
  "trace_id": "uuid",
  "template_id": "top20:book:v1:es",
  "text": "…",
  "placeholders": ["BOOK_LINK"],
  "notes": ["language=es", "intent=book"]
}

4) IF.GOV.PANEL (simulated debates)

What “debate” means here

Because we are not calling external LLMs, the “panel” is a set of deterministic seat evaluators. Each seat emits:

  • a vote (approve | request_changes | veto)
  • reasons (human readable)
  • patch suggestions (structured)

Seat roster (minimum viable, 5 seats)

  1. Safety seat: blocks crisis mishandling; ensures no harmful advice.
  2. Boundary seat: prevents therapy-by-DM; rewrites “help” flows into routing.
  3. Language seat: enforces same-language output; no mixing; handles low confidence.
  4. Privacy seat: avoids unnecessary PII; flags risky asks (phone/email) unless explicitly required.
  5. Next-step seat: checks the reply has a clear next step (link or one question).

Optional seats (when panel size grows)

  • Tone/VoiceDNA seat: checks length + emoji pattern + directness vs DM voice rules.
  • Spam/abuse seat: detects harassment loops and routes to block/report guidance.
  • Contrarian seat: tries to misread the message and see if the draft fails.

Seat output format

{
  "seat": "language",
  "vote": "approve|request_changes|veto",
  "severity": 0.0,
  "reasons": ["..."],
  "patches": [
    { "op": "replace_text", "path": "draft.text", "value": "..." }
  ]
}

Panel aggregation (deterministic)

  • If any seat returns veto → panel decision becomes escalate_human (or urgent_escalate).
  • Else if any seat returns request_changes → apply patches (in order), re-run seats once.
  • Else → approve.

Panel decision record

{
  "panel_version": "if.gov.panel/igdm/v1",
  "trace_id": "uuid",
  "panel_size": 5,
  "seats": [ { "...": "..." } ],
  "decision": "approve_draft|revise_draft|escalate_human|urgent_escalate",
  "final_draft_text_sha256": "…",
  "reason_summary": "short"
}

5) Escalation UX (how Sergio actually sees it)

Escalation record

{
  "escalation_version": "igdm.escalation/v1",
  "trace_id": "uuid",
  "tier": "urgent|needs-human",
  "reason_codes": ["self_harm_signal"],
  "sender_id": "123",
  "mid": "m_abc",
  "time_cet": "2025-12-25T21:13:00+01:00",
  "open_links": {
    "instagram_thread": "https://www.instagram.com/direct/t/<conversation_id>/",
    "fb_inbox": "https://business.facebook.com/latest/inbox/all/?asset_id=<page_id>"
  }
}

Notification strategy (POC)

No paid services required:

  • Show escalations in a logged-in dashboard on emo-social.infrafabric.io.
  • Optional: email later (requires SMTP relay configured); not required for the POC.

6) IF.TTT trace + evidence bundles (provable without leaking)

  • Private bundle (internal): includes raw message text, stored locally with strict permissions.
  • Public bundle (shareable): contains hashes + redacted previews only.

Bundle contents (public)

bundle/
  manifest.json
  event.json
  triage.json
  draft.json
  panel.json
  escalation.json   (only if escalated)
  sha256sums.txt
  signature_ed25519.txt

Minimum “public” fields

  • message_text_sha256 (not raw)
  • draft_text_sha256 (not raw)
  • triage + panel decision + reason codes
  • timestamps (UTC + CET)

This is enough to prove: “given these bytes (committed), these deterministic governance steps happened, and this decision was produced”.


7) Rollout plan (safe)

  1. Triage-only + escalation queue (no drafts yet).
  2. Draft-only templates for Top 20 intents (no sending).
  3. Add simulated IF.GOV.PANEL seats and store panel decisions.
  4. Emit IF.TTT bundles for each event (public + private).
  5. Add comparison table: draft vs actual sent (manual) to measure quality.
  6. Only after measured success: consider limited auto-send for low-risk intents, with a kill switch.