Home Applications ElectionTriage

ElectionTriage

Community Project
This project is maintained by its author and is not officially supported by InterSystems. For technical support, please contact the project developer.
0
0 reviews
0
Awards
2
Views
0
IPM installs
0
Add to bundle
Details
Releases (1)
Reviews
This app has a demo View
An InterSystems IRIS interoperability workflow that triages elec

What's new in this version

First release. Election-day incident triage with a live AI Hub agent inside an IRIS Interoperability production. Tested end to end on 7 November 2026: power-outage report accepted, agent verdict critical, alert fired, incident recorded (session 66, 7 messages, all Completed, no errors).

Election Incident Triage — IRIS AI Hub Agent

An InterSystems IRIS interoperability workflow that triages election-day incidents with an AI Hub agent. An election worker or coordinator submits an incident report; the production normalizes it, the AI agent classifies its severity, recommends an action and drafts the alert text; critical incidents trigger an alert, and every incident is persisted for a simple dashboard.

Built for the InterSystems programming contest "AI Agents in Interoperability Workflows" (development and submission window: 26 October – 8 November 2026). Based on the official ai-hub-dev-template — the template's Sample classes are kept untouched; the app lives in the ElectionTriage package.

Status: tested end to end (7 November 2026). The production runs the full flow live: a power-outage report is accepted, the AI agent classifies it critical, the alert fires and the incident is recorded — session 66, 7 messages, all Completed, no errors. See the demo video.

What it does

  1. REST intake — ElectionTriage.IncidentService receives an incident report as JSON and injects it into the production.
  2. Normalize — ElectionTriage.IncidentProcess (ObjectScript Ens.BusinessProcess, no BPL) trims the free text, defaults the timestamp and falls back to the catch-all category when the incoming category is unknown.
  3. AI triage — ElectionTriage.TriageOperation calls ElectionTriage.TriageAgent (ObjectScript SDK, %AI.Agent), which returns severity (critical / high / medium / low), one recommended action and a short alert text.
  4. Route by severity — the process sends critical incidents to ElectionTriage.AlertOperation (writes the alert to the console log and marks the report ALERTED).
  5. Persist everything — ElectionTriage.RecordOperation stores each triaged report in ElectionTriage.IncidentRecord, which the dashboard lists with the Recent() query (most recent first).

Architecture

HTTP POST (JSON)                     +-----------------------------+
  incident report  -->  IncidentService  -->  IncidentProcess (ObjectScript)
                                     |  normalize
                                     v
                              TriageOperation
                                     |  %AI.Agent (Config Store creds)
                                     v
                     +---------------+---------------+
                     | severity = critical?          |
                     +-------+---------------+-------+
                     | yes                   | no
                     v                       |
              AlertOperation               |
                     |                       |
                     +-----------+-----------+
                                 v
                         RecordOperation
                                 |
                                 v
                         IncidentRecord (dashboard)

Incident taxonomy

The agent uses exactly these 10 LA County categories (validated and renamed to California English terms on 7 November 2026). Typical severity is a guide only — the agent decides per incident.

Category Examples Typical severity
Voting equipment BMD not powering on / frozen; ballot printer fault High–Critical
ePollbook / check-in Check-in tablet down; queue not processing High
Accessibility Accessible voting equipment unavailable High
Supplies Missing provisional ballots / envelopes / signage Medium–High
Staffing Election worker no-show; vote center without quorum Medium–High
Power / connectivity Power outage; vote center internet down Critical
Safety / intimidation Voter being intimidated; electioneering inside the limit Critical
Ballot box / drop box Damaged or full drop box; ballot box fault High
Mail-in voting Discrepancy in a batch of received ballots Medium
Operational question Procedure, hours, voter redirection questions Low

Installation

Requires the AI Hub Community Docker image, build 154 (iris-community-2026.3.0AI.154.0-docker.tar.gz, x64 for Windows). Download it from the Early Access Program portal (requires a login) — this is the one step that needs the developer's account.

# 1. Load the image
docker load -i /path/to/iris-community-2026.3.0AI.154.0-docker.tar.gz

# 2. Make sure the Dockerfile IMAGE matches the loaded image name
#    (default in this repo: docker.iscinternal.com/docker-intersystems/intersystems/iris-community:2026.3.0AI.154.0)

# 3. Create an EMPTY .env file (scaffold stage: no LLM calls run without
#    the Config Store entry below, so no key belongs here)
touch .env

# 4. Build and start
docker-compose up -d --build

Management Portal: http://localhost:52773/csp/sys/UtilHome.csp (SuperUser / SYS). IRIS Terminal: docker-compose exec -it iris iris session iris.

Then start the production ElectionTriage.IncidentProduction from the Management Portal (Interoperability > Productions) or the terminal.

LLM credentials

LLM credentials are resolved from the IRIS Config Store, never from code or from .env. ElectionTriage.TriageConfig reads the entry AI.LLM.triage (Area AI, Type LLM, Name triage) with GetDetails(..., validate=1, resolveSecrets=1) and builds the OpenAI provider from the resolved api_key. Setup, in the IRIS terminal (docker compose exec iris iris session iris), as SuperUser — type the API key only in the terminal, never in chat or in a file:

set $namespace="%SYS"
do ##class(%ConfigStore.DescriptorManager).RebuildRegistry()  // registers the AI.LLM descriptor
write ##class(Security.Resources).Create("AIUseResource")
write ##class(Security.Resources).Create("AIEditResource")
set $namespace="IRISAPP"
write ##class(%Wallet.Collection).Create("AISecrets", {"UseResource":"AIUseResource","EditResource":"AIEditResource"})
set key="sk-..."   // your OpenAI API key, typed in the terminal only
write ##class(%Wallet.KeyValue).Create("AISecrets.OpenAI", {"Usage":"CUSTOM","Secret":{"api_key":(key)}})
kill key
Set llmConfig = {"model_provider": "openai", "model": "gpt-4o-mini", "api_key": "secret://AISecrets.OpenAI#api_key"}
Set sc = ##class(%ConfigStore.Configuration).Create("AI", "LLM", "", "triage", llmConfig)
Do:$$$ISERR(sc) $SYSTEM.Status.DisplayError(sc)

Verify with Set sc = ##class(%ConfigStore.Configuration).GetDetails("AI.LLM.triage", .details, 1, 1) followed by ZWRITE details — the api_key must show the real key, not the secret://... reference. Until the entry exists, the agent's %OnInit() fails loudly with setup instructions.

Trying it

curl -X POST http://localhost:9980/ \
  -H "Content-Type: application/json" \
  -d '{
    "VoteCenter": "Long Beach City Hall",
    "Category": "Power / connectivity",
    "Description": "Power outage at the vote center, voting machines are down.",
    "ReporterName": "Maria Silva",
    "ReporterContact": "[email protected]"
  }'

Expected response: {"status": "accepted", "category": "Power / connectivity"}. Then check the production trace, the agent's severity/action/alert text, the console-log alert (critical incidents) and the ElectionTriage.IncidentRecord table for the persisted row.

Demo video

Watch the demo video (1:31) — narrated walkthrough: the problem, the architecture, a live power-outage report (accepted, category "Power / connectivity"), the production trace (7 messages, all Completed, agent verdict critical, alert fired, incident recorded), and the visual trace of the full flow.

Project layout

  • skills/ — AI Hub agent skills from the template (config store, LangChain, MCP server, ObjectScript SDK, policies, RAG, subagents, toolsets).
  • src/Sample/ — template example classes (tools, toolsets, agents, MCP servers). Untouched.
  • src/ElectionTriage/ — the app:
    • IncidentReport.cls — interoperability message + taxonomy validation.
    • IncidentService.cls — REST Business Service.
    • IncidentProcess.cls — ObjectScript BusinessProcess: normalize → triage → route → persist.
    • TriageAgent.cls — %AI.Agent subclass (system prompt + taxonomy).
    • TriageConfig.cls — Config Store credential placeholder (no keys).
    • TriageOperation.cls — Business Operation wrapping the agent.
    • AlertOperation.cls — critical-alert dispatch (console log + status ALERTED).
    • RecordOperation.cls — persistence for the dashboard.
    • IncidentRecord.cls — persistent record + Recent() query.
    • IncidentProduction.cls — production definition.
  • Dockerfile, docker-compose.yml, module.xml — template wiring, with ElectionTriage.PKG added to module.xml.

License

MIT License — the template's LICENSE is kept as-is, and the ElectionTriage package is released under the same MIT license.

Version
1.0.008 Nov, 2026
Categories
IntegrationAI Agents
Works with
InterSystems IRIS
First published
08 Nov, 2026
Last edited
08 Nov, 2026