Channel states — pick the words
Every state a channel card can be in, with the wordings to choose between. Rebuilt after the source read, which split the problem in two: reachability is one axis with six states, and each surface is its own axis with five. The old single seven-step ladder was wrong — it made one word answer for four independent things.
How to use this. One row per state, options across. My pick is ticked so there is something to argue with. Tick a different one, or write your own beside it — anything you leave alone I will take as agreeing with the tick.
Axis 1 · Reachability — can anything get in or out
Read from connection.configured, connection.active, webhook.mutedLabel and the silence evaluation. First match wins, top to bottom. This is one line on the card, and it genuinely is one fact.
State & condition
Wordings
Never set up!connection.configuredNo connection record exists. Any stored gate values are meaningless.
ANot set upConnect it to start receiving.
BNot connectedNothing is linked yet.
CWaiting to be connected
DNothing here yet
You marked it deadwebhook.mutedLabel !== nullYour own words, from alerts config. Outranks everything below on purpose, so a healthy blip cannot un-say it. Defaults to the bare word "Muted" when you set no text.
A · your label, then the consequenceSwitched off by MetaNothing can arrive and nothing can be sent. You will not be alerted again.
B · label aloneSwitched off by Meta
C · fixed word, label beneathKnown deadSwitched off by Meta
D · when you set no textMuted by youFallback, because the label defaults to just "Muted".
Switched off here!connection.activeA local flag. Nothing to do with Meta, and the wording must not imply otherwise.
ATurned off
BSwitched off by youTurn it back on in Settings.
CPaused by you
DDisabled here
Nothing has ever arrivedwebhook.silent === null
(lastEventAt is null)Documented as unknowable, not OK. Different from having gone quiet — this channel has never once been heard from.
ANothing has ever arrivedConnected, but Meta has never sent anything through.
BNever heard from
CNo sign of life yet
DConnected, untested
Gone quietwebhook.silent === trueNothing for N counted hours, where counting is 24/7 or business-hours-only per your config. A weekend does not count in business-hours mode.
AGone quietNothing for 9 hours.
B · names the windowGone quietNothing for 9 working hours. Your alert threshold is 6.
CNothing coming inLast thing arrived 9 working hours ago.
DStopped hearing from Meta
Receivingwebhook.silent === falseThe healthy case. Says nothing about whether the bot acts — that is axis 2.
AReceivingLast thing arrived 4 minutes ago.
BConnected and busy
CMessages coming in
D · no word, just the factLast thing arrived 4 minutes ago
Axis 2 · Each surface — what the bot does about it
One row per surface per state. These are independent of axis 1: a channel can be receiving while every surface is off. The wording has to change per surface, because "live" on moderation means hiding and on comments means replying.
Reply to comments Instagram Facebook
livegates[…:comments] === "live"
AReplying
BAnswering comments
CLive
shadow=== "shadow"Writes a reply, posts nothing, queues it for your approval.
ADrafting only
BWaiting for your OK
CWriting, not posting
off=== "off"Comments still arrive and are stored. Only the reply is off.
AOff
BNot replying
CYou answer these
Hide or delete bad comments Instagram Facebook
live…:moderation === "live"
AHiding bad ones
BCleaning up
CModerating
shadow=== "shadow" · the defaultDecides and logs, hides nothing.
AFlagging, not hiding
BWatching only
CMarking for you
off=== "off"No moderation pass runs at all. Anything nasty stays up.
AOff
BNothing is being checked
CNot moderating
Answer messages Instagram WhatsApp Facebook
live…:dms === "live"
whatsapp === "live"
AAnswering
BReplying to everyone
CLive
canary WhatsApp onlywhatsapp === "canary"
+ canaryIds[]An allowlist. Everyone not on it gets nothing at all — the riskiest state to word vaguely.
A · names the countAnswering 3 test numbers onlyEveryone else gets no reply.
BA named few only
CTesting on an allowlist
shadow…:dms === "shadow"Drafts a reply, sends nothing.
AWaiting for your OK
BDrafting only
CWriting, not sending
off=== "off"Messages still arrive and are stored. This is the one every earlier mockup got wrong.
AOff
B · says where they goArriving, nobody answeringThey land in the Inbox for you.
CYou answer these
not built Facebookno pipeline existsNot a setting. No ingestion, no adapter, no sender.
ANot built yetMessenger is not wired up.
BNot available
CComing later
Open a DM from a comment Instagram Facebook
live…:comment_to_dm === "live"
AStarting DMs from comments
BTaking it private
CLive
shadow=== "shadow"
AWaiting for your OK
BDrafting openers
CProposing only
off=== "off"
AOff
BNot starting DMs
CComments stay public
dark Facebooktoken has no messaging scopeThe gate exists and can be flipped; flipping it would do nothing.
ANot built yetThe Facebook login needs a wider permission first.
BBlocked by permissions
CNot available
What this costs to build. Axis 1 is fully available today. Axis 2 needs six gates the payload does not carry, and the Facebook rows need the channel to exist at all — WEBHOOK_SOURCE, HomeToday.messages, the HomeChannel union and errors24h all stop at Instagram. Picking words here does not depend on that; building them does.