Source-blind inputs that advance threads. Nine channels, one canonical shape.
Method step: Watch. What advances every live thread, regardless of where it came from.
Most operational systems assume one stream of truth: events arrive on their own, humans process them. That works when events are external (sensors, ERPs, webhooks) and humans pick from queues at their own pace.
But in real operations, the most important signals are often absences — the promoter who didn't check in by 09:15, the KYC that didn't get submitted, the brand approval sitting for three days, the invoice now overdue. Absence-as-signal cannot be detected from event streams alone.
Earlier drafts of ContextOS named three streams — events, interactions, heartbeats — as parallel logs. That was useful but incomplete. Real operations don't have three streams; they have many sources of stimulus, all arriving in the same canonical shape, playing one of three roles.
A stimulus is any input that may advance a thread.
It is source-blind: the engine doesn't care where it came from once it's normalized into the canonical envelope.
The "three streams" framing lives on as the three roles a stimulus plays on its target thread:
Roles are how we describe what a stimulus does to a thread. Channels are how we describe where it came from. Same stimulus, two questions, two answers.
Stimuli arrive through nine channels. Each has its own auth, dedup, latency, trust, and parsing concerns. Once normalized, all nine produce the same canonical envelope and feed the same downstream pipeline.
An in-app human CTA. A promoter taps Check-in. An agency ops lead presses Lock Roster. A finance manager approves an invoice. The highest-volume channel; subject to fraud detection (selfie, geo, device fingerprint) and reconciliation against expected events (was the button press answered by the corresponding fact?).
Inbound HTTP from a 3rd-party system. ZATCA returns a stamp. Stripe confirms a settlement. Meta WhatsApp confirms delivery. ERP returns an acknowledgement. KYC vendor returns a result. Authenticated by HMAC signature, mTLS, or signed JWT.
A parsed inbound email. A brand replies "approve" to a report-ready email. A supplier confirms an order via reply. A complaint is forwarded with attachments. Authenticated by DKIM/SPF/DMARC pass; routed by a per-thread reply token in the address.
A reply to an outbound SMS. A supervisor ACKs from a feature phone. Most useful where smartphone access isn't reliable. Authenticated through the SMS provider's webhook; matched to the thread by the reply token in the message.
A pull from a sibling internal system on a schedule. HR exports the daily roster. The biometric attendance device exports its punch log. The finance ERP exports invoice acknowledgements. Authenticated by service account or SSH key; schema-validated on read.
An AI agent acted on a thread. The system auto-classifies a complaint. AI proposes a roster swap. AI flags a possible deepfake selfie. Every AI action carries its confidence score and the named features that fed it — the audit record is fully reproducible from input + model version + output.
The engine fires a scheduled tick. Per-thread heartbeats are the most common case; cross-thread sweep heartbeats run on cron (dead-chain detection, dead-button detection, confidence calibration). The scheduler is part of the engine; identity is system.
The system itself emits an event as a side-effect of normal business processing. A successful payment posting emits a payable-statement-generated event. A KYC import from external_log emits a downstream KYC event. Without this channel, in-app system events would be the one ambiguous case — this keeps the model uniform: every event has a stimulus_channel.
An IoT or sensor reading. Footfall counter at a store entrance. Smart-shelf weight delta. BLE beacon at a rendezvous point. Phase-4 only for most tenants; physical sensor data is classed by privacy class (a counter is low-PII; a face-detection camera is high-PII and intentionally out of scope for now).
Each channel is implemented as a sealed adapter that does the same ten things. Once those ten things are done, the canonical event is indistinguishable from any other event downstream.
Adding a new channel is exactly that work, no more. The engine doesn't change. Existing pipelines don't change. The site builders don't have to learn a new model. New integrations slot in.
All stimuli, once normalized, carry the same envelope. The shape is structured, not text. Notifications are derived from this structure at delivery time, in the recipient's locale, by their channel constraints.
{
"event_id": "evt_01HW...",
"event_type": "attendance.checked_in",
"stimulus_channel": "user_action",
"stimulus_id": "stm_...",
"thread_id": "thread.shift.sh_abc123",
"thread_step": "step_awaiting_check_in",
"thread_role": "progression",
"occurred_at": "2026-05-01T13:42:11Z",
"received_at": "2026-05-01T13:42:13Z",
"correlation_id": "cor_...",
"causation_id": "evt_...",
"tenant_id": "...",
"agency_id": "ag_...",
"actor_type": "promoter | system | ai_agent | external_system | ...",
"actor_id": "...",
"locale": "en-AE",
"tz": "Asia/Dubai",
"pii_class": "none | low | high",
"payload": { /* event-specific */ }
}
Three new envelope fields make the substrate explicit: stimulus_channel tells us which adapter produced the event, stimulus_id points back to the raw stimulus in the channel's append-only store, and thread_id/thread_step/thread_role make thread membership first-class.
Not all stimuli are equally trustworthy. A government webhook signed via mTLS deserves higher base trust than a parsed inbound email from a personal domain. Channel trust feeds the confidence model directly.
| Channel | Default base trust | Notes |
|---|---|---|
| user_action (operator role) | 0.95 | In-network operator with permissions |
| user_action (end-user) | 0.85 | Subject to fraud detection |
| webhook (gov mTLS) | 0.99 | Government-grade source |
| webhook (HMAC-signed) | 0.95 | Provider-grade |
| webhook (delivery callback) | 0.90 | Reliable but not authoritative |
| email_inbound (DKIM, brand domain) | 0.85 | Subject to free-text ambiguity |
| email_inbound (DKIM, personal) | 0.50 | Requires extra confirmation |
| sms_inbound (token-matched) | 0.80 | Numeric tokens only |
| external_log (registered ERP) | 0.90 | Schema-validated |
| ai_action | per-payload | Confidence carried in event |
| scheduled | 1.00 | The fact that it fired is certain |
| app_internal | 1.00 | Internal code is trusted |
| device (calibrated) | per-device | Drifts; recalibrated periodically |
Trust scores feed routing. An invoice-collected event from webhook(payment_gw) may auto-close the invoicing thread. The same event from email_inbound requires human confirmation before the engine acts on it.
Meet heartbeats — the thread's own pulse, scheduled at chain-birth, fires when an expected stimulus is overdue.
Calm technology with teeth.