Upstream connectors Beta
Intent is born where work is asked for. Upstream connectors put Triage’s diagnostic questions inside the tools requesters already live in (starting with Microsoft Teams) so the decision is made at the moment of need. composerID then carries that decision downstream into the systems of record.
Nothing about the diagnostic moves into the chat platform. The questions, the scoring, the routing and the audit spine all stay where they live today — the Intake Gateway only translates between chat cards and the same decision API the web intake uses.
The Teams app package
A manifest, icons and an Entra app registration — installed once per tenant from the org catalog, authorised with a single admin consent. Nothing is deployed inside the tenant; the package only points at the gateway.
The Intake Gateway
Receives bot activities, verifies the requester via Entra SSO, renders questions as Adaptive Cards and translates submissions back into answers. It holds the conversation position — and nothing else. Renderer‑agnostic by design: Slack is the same core with a Block Kit renderer.
The decision core, unchanged
The gateway calls the same evaluate contract as the web intake. Scoring, routing, anti‑gaming pattern detection and Compliance File generation are server‑side and identical regardless of where the questions were asked.
The full journey. Steps 1–8 are the upstream connector; from step 9 the flow is standard composerID publishing — the same five stages documented in How integrations work.
| Step | What happens | Where it runs |
|---|---|---|
| 1 | The requester opens the Triage bot in Teams — or is pointed at it the moment they ask for work in a channel. | Teams |
| 2 | Identity is verified silently via Entra ID SSO; no separate login. Contextual data is fetched in the background where the tenant tier allows. | Gateway → Entra ID |
| 3 | The first question arrives as an Adaptive Card: prompt, embedded guidance, choice answers. | Gateway → Teams |
| 4 | The answer is submitted; the card is replaced in place by its locked state — no inputs remain. | Gateway |
| 5 | The next question card arrives. One card per question, fixed order, however many questions the tenant’s diagnostic defines. | Gateway → Teams |
| 6 | On the final answer the gateway hands the complete answer set to the decision core; scoring and routing produce the channel decision. | Triage decision core |
| 7 | The Intent Record is minted — one traceable Intent ID. The Compliance File records the intake surface and the verified requester identity on the audit spine. | Triage decision core |
| 8 | The completion card shows the recommended channel, confidence, rationale and the intent:// chip. | Gateway → Teams |
| 9 | composerID preflights and publishes the intent into the destination system(s) of record, idempotently. | composerID |
| 10 | The publish receipt lands: the completion card gains a deep link to the created record. If a destination needs a missing field, the enrichment request returns to the same thread — as another card. | composerID → Gateway → Teams |
The intake has deliberate properties — they are what make the decision defensible. Each one maps to a card mechanic, so the chat surface enforces them by construction rather than by policy.
| Intake property | How the cards enforce it |
|---|---|
| One question per screen | One card per message. The next question only arrives after the current one is answered. |
| Answers lock on submission | The submission replaces the card with a version that has no input elements left. There is nothing to edit. |
| No back button | Earlier cards are inert text, and the gateway rejects out-of-order or repeated answers. |
| Anti-gaming pattern detection | Runs server-side in the decision core — identical to the web intake, invisible to the surface. |
| Abandonment leaves no record | If the thread goes quiet mid-flow, partial answers are not persisted: no Compliance File, no Intent Record. |
Identity
Entra ID SSO verifies the requester silently — the person answering is the person signed into Teams. That verified identity rides the audit spine into the Compliance File, so “who asked for this?” is answered by the record, not by archaeology.
Tenancy
The app package is published to the tenant’s org catalog and authorised with one admin consent. Per-tenant configuration — the question set, tiers, contextual data sources — lives in Triage, not in the package, so updating the diagnostic never means reinstalling the app.
| Case | Behaviour |
|---|---|
| SSO fails | The intake does not load; the error is shown by the surface, and nothing reaches the decision core. |
| Admin consent absent | The install blocks before any data flows — consent is the gate, once, for the whole tenant. |
| Requester abandons mid-flow | No partial answers persist. No Compliance File, no Intent Record. |
| Client drops mid-flow | Conversation state is server-side; the thread resumes at the current question on any device. |
From the moment the Intent ID is minted, this is the standard composerID flow: preflight against the destination’s tenant requirements, idempotent publish keyed {intent_id}-{version}-{destination}, external IDs and a receipt on the timeline, webhooks and reconciliation keeping the record truthful after go-live. Two returns are specific to the chat surface:
The deep link
When the publish receipt lands, the completion card is updated with a link straight to the record composerID created — the requester watches their ask become a requisition, an SOW or an agreement without leaving the thread.
The enrichment loop
If preflight finds a gap the diagnostic didn’t cover — a cost centre, a location code — the enrichment_request comes back to the same thread as, naturally, another card.
The upstream/ package is the executable version of this page — pure stdlib, no network, same conventions as the adapter spine. The intake properties above are pinned by its contract tests.