Soup to nuts

What actually happens to a ticket

A ticket is born in the ERP helpdesk. It is polled, verified, classified, resolved to a client and a machine, acted on — or handed to a human with everything already checked. Then it teaches the system something.

Where the pieces live. The helpdesk (ERP) owns ticket state. The RMM owns devices, agents and the AI's execution. The bridge is a Node service that runs the model and exposes both as tools. The database keeps a shadow of every ticket the AI has an opinion about.

Arrival — and three different kinds of ticket

Everything lands in the ERP helpdesk, because the helpdesk is the single source of truth for ticket state. The AI never owns a ticket; it reads and writes it through an API, as a named service identity.

OriginShapeHandling
Person, by email or portalfree text, no structuretriage, then evidence
Monitoring platform[ALERT] prefix, host in the bodyverifier first, model second
The AI itselfscheduled task, bulk fleet job, reportdeduplicated by key

Poll — 90 seconds, with a watermark

A scheduled job asks the helpdesk for open tickets in the configured teams and open stages, since the last watermark. Each ticket is reconciled against the AI's own shadow record: unknown → triage; changed, or a new message → re-engage; vanished → clean up.

every 90 s
poll      open tickets, team=Support, stages=[New, In Progress, Waiting]
filter    scope: requester domain, or "always look at alerts"
upsert    shadow record keyed by ticket ref (unique)
enqueue   triage task per new or changed ticket

Verify — the part that is deliberately not an LLM

For alerts, a rule engine runs before a model sees anything. It matches the alert type, proves the host belongs to that client, collects read-only evidence from the device, and produces a verdict. Noise and already-recovered conditions can be closed without ever calling a model.

  • rule match
  • host ownership proof
  • read-only probe
  • verdict: benign · actionable · unknown

Why: a model reading only the ticket text is guessing. Evidence is cheap; a wrong closure is not.

Triage — one question, not a conversation

The model receives the ticket plus the verified facts and answers a single structured question: alert-clean, alert-actionable, regular, or unknown. It cannot close anything at this stage. Its output is a classification, not an action.

Resolve — client, site, machine, article

Identity is derived, not asked for: requester domain → ERP company → RMM client → device (by logged-in user, hostname, or a mapped record). Then the client's KB is searched for a matching situation.

Shared infrastructure is why this is code and not a guess: 32 hostnames in the estate are used by more than one client. The resolver is deliberately conservative, and says ambiguous instead of picking one.

Decide — after the evidence, before the action

With evidence in hand the system can act, but only along paths that were authorised in advance:

DispositionWhat may happen without a human
benignnote, and close — if the procedure is approved and auto-enabled
customer_actionnote, and a drafted reply that waits for a technician
our_actionread-only work unattended; any change needs approval
needs_humanstop, open a decision chat, attach everything found

Ask — the decision chat (/ai-decision/<token>)

When the AI cannot prove something, it does not invent a machine name. It tags the ticket, mints a single-use token, and emails the technician a link. That link opens a stateful chat: the session that paused is resumed, with every tool call it already made in the room.

  • works from a phone
  • same session, not a new chatbot
  • first technician message assigns the ticket
  • approvals captured in-chat are written to the ticket

Act — through one channel, under capability gates

Device work happens through the RMM agent that is already on the machine: PowerShell or bash, as root or the console user. Read-only is the default. Writes are class-gated, and the surface matters — an unattended scheduled task may create, note, read and write knowledge; it may not reboot a server.

action classes
read      get device, run read-only command, list processes, read event log
write     run script, kill process, reboot, resize, install
destruct  delete data, remove users, wipe — never unattended

gate      capability profile × procedure status × live approval
record    every action: who asked, what ran, what came back, rollback

Close or reply — only on an instruction

A customer-visible reply or a ticket closure needs a human sentence in the conversation. That sentence is copied onto the ticket, attributed, so the reason survives the chat window. Deferred sending exists as a designed path (hold, with a human-takeover veto) rather than an unlocked one.

Learn — three kinds of memory, kept apart

MemoryWhereWho may write it
Procedure (the rule)database row: match, evidence, fix, verificationAI proposes a draft; a technician approves
Client knowledgeERP KB article per companyAI appends, with the ticket as provenance
Device notesthe agent recordAI, with the run that produced them

The product code holds one generic engine and no vendor names. Vendor knowledge is data a technician can read, edit and approve.

Report — including what was not measured

A daily report and a scheduled review summarise tickets, minutes and spend. Work that cannot be attributed is reported as unmeasured, never as zero: a quiet day and a lazy day look identical in an hours field, and the system refuses to conflate them.

Vocabulary

Four words that mean something specific here

Procedure

A rule, in prose for humans and in a structured match block for the machine. Carries the evidence it needs, the fix, the verification, and a disposition. It may rule alone only when it is approved and auto-enabled.

Automation group

The per-client permission to automate: which procedures apply, which mode (advise, read-only, fix), which machines are in scope, and whether the AI may close. Separate from the worker team — the group of model workers, each with a role and a model.

Ticket state

The ERP owns it. The AI keeps a shadow record with its own lifecycle (new, claimed, triaging, awaiting customer, working, escalated, handed off, skipped, error) purely so it knows what it has done.

Ledger

Minutes and money, append-only. Corrections are new rows that point at the old one. A number you cannot recompute is labelled estimated rather than presented as fact.

What the system is not. Not a chatbot answering from the ticket text. Not a closer of tickets at any cost. Not a place where a credential becomes visible to a model: reads return placeholders, values are injected into the tool only, and a tool call carrying a known secret is refused.