1. Platform overview

Traffic Lights orchestrates business processes in which humans, AI agents and machine systems are first-class participants. Each participant emits and receives the same standardised events, operates under the same versioned policies, and appears in the same audit record.

The platform separates two things most tools combine:

  • Execution — what runs next. Handled by rules over the process graph.
  • Decision — what should be done about an outcome. Handled by versioned policies: retry, escalate, notify.

Traffic Lights does not replace your execution engines. It sequences them, decides what happens when they produce an outcome, and records who decided what.

What the platform provides

CapabilityDescription
Process orchestrationAuthor a process as tasks, flows, actions and policies. Flows carry conditions, so a process can branch on the content of an event.
Human-in-the-loopA process pauses at a human task, an approver decides, and the process resumes. Approve, reject and delegate are all first-class.
Agent participationAI agents propose actions and are recorded as agents — distinct from both people and machines — in every audit view.
Independent corroborationA task can compare a proposed value against an independent record and refuse when they disagree, without a person in the loop.
Policy-driven decisioningVersioned, effective-dated policies decide retry, escalation and notification. Changing a policy does not require a deployment.
Real-time healthEvery process and run carries a derived Red / Yellow / Green state with full lineage to the event that produced it.
Audit by defaultEvery event, decision and approval is recorded with an actor, a timestamp and an outcome. The record is append-only.

2. Core concepts

TermDefinition
ProcessA definition: a set of tasks, the flows connecting them, the actions they dispatch, and the policies that govern them. Versioned and effective-dated.
TaskAn atomic unit of work. A task is machine-executed, human-decided, or agent-proposed.
FlowA directed edge between tasks. Carries an optional condition that gates whether the downstream task dispatches.
ActionWhat a task actually does when dispatched. A task may fan out to several actions.
PolicyA versioned rule governing what happens in response to an outcome — retry, escalate, or notify.
RunOne execution of a process. Identified by a run ID that correlates every event, decision and record end to end.
EventA standardised message emitted by a task, an agent, an external system, or the platform itself.
Traffic stateDerived health: Green (healthy), Yellow (attention needed), Red (critical).
PrincipalAn identity that acts: a person, a service, or an agent. Resolved and displayed differently for each.

2.1 Execution types

A task declares what kind of participant executes it. This determines how the platform dispatches it and how it appears in the audit record.

TypeExecuted byBehaviour
MachineA systemDispatched to an action; completion is reported back as an event.
Human sign-offA personThe run pauses. An approver approves, rejects or delegates.
Agent proposalAn AI agentThe agent proposes an outcome. The proposal is recorded as a proposal, attributed to the agent, and is subject to the same policies as any other outcome.
CorroborationA checkerCompares a claimed value against an independent record and returns confirmed or rejected. The comparison is made by the checker; the platform records the verdict and branches on it.
No-op—A marker step. Records that a stage was reached without dispatching work.

Why corroboration is separate. A corroboration is not a task someone performs. It is an independent comparison whose verdict the process branches on — so an agent's confident proposal can be refused by a check that never asked the agent. The audit record shows both the proposal and the refusal.

3. Authentication

Every route is authenticated. Two methods are supported.

MethodHeaderUse
Bearer tokenAuthorization: Bearer <token>Interactive callers. A person signed in through the application, or a service acting with a user's identity.
API keyX-API-Key: <keyId>.<secret>Machine callers. The secret half is returned once when the key is minted and never again.

Bearer wins. A route consults the API key only when no Authorization header is present. An empty or placeholder Authorization header silently disables the key. Machine callers must send no Authorization header at all.

3.1 API key scopes

A key carries one or more scopes. Scopes are exact and are not hierarchical.

ScopeGrants
readRead routes.
audit:writeThe approval-history write route, and nothing else.
principal:resolveResolving a set of identifiers you already hold into display names and delivery addresses. Cannot list, cannot search, refuses empty or wildcard requests.
ingestReserved for event submission. No endpoint accepts it yet — see Section 12.

Scopes are not a disjunction. A key holding audit:write is refused by every read route. A key minted with an unrecognised scope is dropped at resolution and returns 401 — indistinguishable from an invalid key.

4. REST API

Base URL: https://api.<environment>.traffic-lights.io. All business routes are under /api/v1.

4.1 Health

MethodPathAuthResponse
GET/healthNone200 {"status":"ok"}

4.2 Processes

MethodPathNotes
GET/api/v1/processesList process definitions for your tenant.
POST/api/v1/processesCreate a process definition. Versioned on write.
GET/api/v1/processes/{id}/runsRun history for a process.
GET/api/v1/processes/{id}/statusCurrent derived health and per-task state.
GET/api/v1/processes/{id}/policiesPolicies attached to a process.

Tasks, flows and actions are created and read under /api/v1/tasks, /api/v1/flows, /api/v1/actions and are always scoped to a parent process.

4.3 Policies

MethodPathNotes
GET/api/v1/policiesList all policy types available to your tenant.
POST/api/v1/policiesCreate a policy. Effective-dated on write. Changing a policy does not require a deployment.
GET/api/v1/policies/{id}Read a specific policy version.

Two policy types do nothing. Delegate and branch policies are accepted, stored and returned by the API, but nothing acts on them. Use retry, escalate, notify and halt. See Known limitations.

4.4 Approvals

MethodPathNotes
GET/api/v1/approvalsList pending approvals for the authenticated caller.
GET/api/v1/approvals/{id}Read a specific approval with full context.
POST/api/v1/approvals/{id}/approveSettle as approved. Run resumes.
POST/api/v1/approvals/{id}/rejectSettle as rejected. Accepts optional reason field. Run does not continue past the rejected task.
POST/api/v1/approvals/{id}/delegatePass authority to a named delegate. Hop recorded in the decision chain.

4.5 Approval history

MethodPathNotes
POST/api/v1/approval-historyWrite an approval history record. Requires audit:write scope. Append-only.
GET/api/v1/approval-history/{runId}Read the complete decision chain for a run.

4.6 Principal resolution

MethodPathNotes
POST/api/v1/principals/resolveGiven identifiers you already hold, returns display name, identity kind and delivery address. Requires principal:resolve scope.

Deliberately narrow. This route converts an identifier you possess into an address. It cannot discover one you do not have — there is no listing form, no search by name or email, and an empty or wildcard request is refused.

4.7 Error behaviour

  • A first request to an idle service may take several seconds. Retry once.
  • Validation failures return 422 with a structured detail array — one entry per field, naming the field path, the rejected value and a machine-readable error type. All violations are reported, not just the first.

5. Events

Every participant communicates through the same event shape. An event carries an envelope, which says what kind of event it is, and a detail, which carries the facts.

{
  "source":      "sai.tl.router",
  "detail-type": "FLOW_COMPLETE",
  "detail": {
    "runID":    "MEC-20260827T042400Z",
    "taskID":   "20001202",
    "status":   "SUCCESS",
    "severity": "INFO",
    "message":  "Flow complete"
  }
}
FieldLevelDescription
sourceenvelopeWhere the event came from.
detail-typeenvelopeThe event category.
runIDdetailThe correlation identifier, end to end. The most important field in the system.
taskIDdetailWhich task the event concerns.
statusdetailSTARTED | SUCCESS | FAILED
severitydetailERROR | WARN | SUCCESS | INFO | DEBUG
messagedetailHuman-readable description.
timestampdetailStamped automatically.

Severity is not decoration. Notification delivery filters on severity before choosing a channel. An event that omits severity defaults to INFO, which is below the default threshold and is suppressed. An emitter that builds its detail from scratch must set severity explicitly.

5.1 Conditions on flows

A flow may carry a single comparison that gates whether its downstream task dispatches: a path into the event, an operator, and a value.

detail.status == FAILED

Conditions fail open. An expression the parser cannot read is treated as true, with a warning. A malformed gate is indistinguishable from a satisfied one and the branch runs. Keep conditions to a single comparison.

6. Approvals, delegation and expiry

A human task pauses the run and creates a pending approval addressed to a principal. Four outcomes are possible.

OutcomeMeaning
ApproveThe run resumes and the next task dispatches.
RejectThe decision is recorded with an optional reason. The run does not continue past the rejected task.
DelegateAuthority passes to a named delegate. The pending approval is repointed and the hop is recorded in the decision chain.
ExpireNo person decided within the window. The platform settles the approval as expired and the task reads as blocked. The audit record shows expiry, not rejection — the absence of a decision is not a decision.

6.1 The decision chain

Every approval carries a chain showing who did what, in order, with timestamps. A delegated approval shows the delegator, the delegate, and who ultimately decided. The chain names people, services and agents distinctly — a delegation to a colleague and an action by a service are never displayed the same way.

Delegation depth. The chain displays how many delegations have occurred and how many are permitted. The permitted count is currently a display value; the platform does not yet refuse a delegation that exceeds it.

6.2 Identity in the audit record

Every actor in a decision chain is resolved to one of five kinds.

KindMeaning
PersonResolved to a named member of your tenant.
ServiceA platform component acting under its own identity.
AgentAn AI agent, shown by the label it was assigned. Agent labels are displayed exactly as written and are never looked up as people.
UnknownThe identifier was looked up and no matching member was found.
UnresolvableThe directory could not be read at all.

Why the last two are separate. "We looked and found nobody" and "we could not look" are different facts. Collapsing them would let a directory outage read as a missing person.

7. Notifications

Notifications are delivered when a policy asks for one, when an approval is requested, and when an approval breaches its deadline.

AspectBehaviour
ChannelsEmail and Microsoft Teams are implemented. Other channels are not.
RecipientFor an approval request, the assignee is resolved to a delivery address at send time. There is no fallback address — if the recipient cannot be resolved, the platform refuses to send and records why.
Severity thresholdA per-tenant threshold suppresses events below it. Notifications a tenant explicitly asked for — an authored policy or an approval request — are delivered regardless of the threshold.
DeduplicationRepeated notifications for the same task and the same state within a short window are suppressed. Different runs of the same process are always distinguished.
Per-tenant configChannel credentials and delivery settings are held per tenant. A tenant with no configuration is refused rather than defaulted to another tenant's channel.

8. Agents and the MCP surface

Traffic Lights exposes its API as a tool surface for LLM-driven agents, so an agent can read processes, examine runs, author drafts and settle approvals through the same authenticated routes a person uses.

  • An agent acts as the caller whose credential it holds. It cannot name a tenant — that parameter does not exist on any tool — and every write is stamped with the tenant from the credential.
  • Agent actions appear in the audit record as agent actions, distinguishable from both people and services.
  • Process drafts can be created, previewed and finalised, so an agent can propose a process definition for review before it becomes live.

Agents propose; policies decide. An agent's proposal is an outcome like any other. It is subject to corroboration, to approval, and to the same policies. Nothing an agent proposes bypasses a gate a human would have faced.

9. Multi-tenancy

Every record is scoped to a tenant, and the tenant is always taken from the caller's credential — never from the request body. A request that names a different tenant does not reach another tenant's data.

  • Process definitions, runs, approvals and audit history are all tenant-scoped.
  • Two tenants may use the same process names without collision.
  • Directory reads return only your tenant's members. Platform staff are withheld from tenant directories.

9.1 Roles

RoleMay
AdministratorAuthor and modify process definitions, policies and users. Settle approvals.
Process ownerSettle approvals. Read everything in the tenant.
ApproverSettle approvals. Read everything in the tenant.
ViewerRead only.

Shared authority. Any holder of an approving role may settle an approval, not only the named assignee. Today the approvals list shows each user the approvals addressed to them specifically — so an approval a colleague could settle may not appear in their list. This is being addressed.

10. Retry and escalation

A failed task can be retried under a retry policy, and a task that breaches its deadline can escalate under an escalation policy. Both are authored as policies rather than configured in code, so they can be changed without a deployment.

ConceptBehaviour
Retry policyGoverns how many attempts a failed task receives and with what delay.
Circuit breakerRefuses further retries after repeated failures within a window, then allows a single probe attempt before closing.
Escalation policyFires when an approval passes its deadline. Names who to escalate to and through which channel.

Retry is not a governance decision. A policy reacts to an outcome a task produced. A mechanical retry reacts to no outcome at all — the attempt did not land, and nothing decided anything. Where retries exhaust is where a governance response begins.

11. Known limitations

Each of these is current, measured, and visible to you through the API. They are listed so this guide does not assert capability the product does not have.

LimitationDetail
Two policy types do nothingDelegate and branch policies are accepted, stored and returned by the API, and nothing acts on them. Halt policies are enforced. Use retry, escalate, notify and halt.
A run has no deadlineA task has a deadline and an approval has a deadline. The run itself does not. A run that stops making progress stays open until somebody notices.
An abandoned run reads as runningA run whose work has stopped is shown as in flight, not as stalled. One run read as healthy for thirteen days.
Approval windows not honouredAn approval policy may name its own window in seconds. That value is not carried into the store the engine reads, so every approval falls back to the deadline of the task it sits on.
Escalation resolves to the sweepEscalation is evaluated by a periodic sweep that runs every thirty minutes, so an approval that names a five-minute window escalates on a thirty-minute boundary.
Conditions fail openAn unparseable flow condition is treated as true and the branch runs.
Branches cannot rejoinMutually exclusive branches cannot converge on a shared downstream task. A conditional split needs a complete path on each side.
A false condition ends its branchA skipped step does not continue past itself. There is no "skip this step and carry on".
Delegation is unboundedThe permitted-hops value is displayed and not enforced.
Approvals listed by assignee onlyA role-holder who is not the named assignee can settle an approval that does not appear in their list.
Task lists show identifiersThe process definition view shows raw identifiers rather than names. Run detail and the approvals list resolve names correctly.
Self-approval not preventedThe platform does not record who requested a run, so it cannot refuse an approval by the requester.
Retry has not executedImplemented; no retry has run in a live system.

12. Not yet available

These are planned and are not built. They are named here so that nothing in this guide reads as though they exist.

CapabilityStatus
Event submission over RESTExternal systems cannot yet submit events over the API. A scope is reserved for it and no endpoint accepts it.
One-tap approval from emailApproval notifications link into the application, where you sign in and decide. Deciding directly from the email without signing in is not yet available.
Segregation-of-duties controlsPreventing a requester from approving their own request requires the platform to record the requester, which it does not yet do.
Structured input on an approvalAn approver may approve, reject or delegate. A decision cannot yet capture structured input — acknowledgements, required fields, or anything the process author wants recorded alongside the decision.
Attaching an outcome to a runA defect, complaint or incident discovered later cannot yet be attached to the run that produced it.
Fan-in on the process graphTwo branches cannot converge on a shared downstream task, so a conditional split needs a complete path on each side.

A claim you can check is a claim that must hold when you check it. Everything in Sections 11 and 12 is verifiable from the API by anyone with a key — which is why it is here rather than omitted.