Skip to main content
Design only. Nothing on this page is implemented, and none of it starts without explicit approval - PR by PR, in the order at the end. Today the process support is the orchestrator’s fixed sequence of loops (Pipeline), switched by auto_* flags, with one LLM classifier on the Erstkontakt mailbox.
The examples this design follows come from the exnatonCONFERENCE 2026 (Zurich, 21 October 2026): Exnaton’s agent harness and its Exception Handler, live on one Austrian tenant, and the product ideas drawn from it (“Market Exception Handler”, “Market Process Skills”). What Exnaton showed is the shape; what the bridge already has is the material. The design keeps everything deterministic that must stay deterministic - schedules, EDIFACT, deadlines - and makes agentic exactly the part that is agentic in people’s heads today: noticing an exception, deciding what to do about it, doing it, and learning from the answer.

What the conference proved, and what it means here

Everyone buys the model from the same providers; the harness is the difference. Exnaton’s harness has three parts: Access (which systems the agent may read and write, with the rights of the people, often fewer), Skills and memory (codified expertise: runbooks, market processes, case notes), Control (approvals, guardrails, logs; every change is a case a human approves; every rejection is learned from). The bridge has all three as material already: the process API with its scopes, the docs and the regulatory KB, the audit trail and the event catalog. It has none of them as a harness.
One Austrian tenant: 42,426 accounts, billability 96.7 % to 99.79 % in five days, 1,313 accounts recovered, every case an EDA process (ECON, ANFORDERUNG_PT, code 94). The loop is: validation failed → reprocess; transmission faulty → request again; not sent → request again; resend rejected → check master data or insist; after every action the agent re-reads the status; what is left, the agent writes to the grid operator. That loop is, process for process, the bridge’s PARTIN/ZOE/APERAK/MSCONS exchange with Netzbetreiber - today spread over resend_rejected, nachversand, korrektur_mails, quittungs_nachfass, stammdaten_anfragen, auskunft_antworten and aktivierung_nachfass, each its own loop with its own flag.
  1. Autonomy per agent in three steps: propose only, act with approval (every write waits for an operator; reads and proposals do not), act. Dry run for the first week.
  2. Rules as numbered, citable data, not prose. A shared policy (P1 to P30) applies to every agent; an agent’s own rules continue the numbering; a run cites rules by number (“per policy P13”).
  3. An inbox, not a log. Tabs: To approve, For a person, Improvements, Failed, All open, Done. Each case carries a risk score, a category (ESCALATE_INTERNALLY, NEEDS_INVESTIGATION, SWEEP), the actions, the age, and an Instruct the agent field in plain language that becomes policy.
  4. A fixed outcome taxonomy so impact can be measured: fixed by the agent, fixed by a human with the agent, resolved by the counterpart after an agent-initiated message, no action needed, dismissed. Plus stale (open for more than 7 days).
  1. Event triggers. Exnaton’s harness runs on cron only; “On an event” is greyed out. A market-side agent lives on events and deadlines: an APERAK is due 45 minutes after a UTILMD, the day-ahead gate closes at 14:30, MaBiS has its own calendar. The bridge already computes all of these; the agents must be triggered by them.
  2. Enumerate the checks, run all of them, every time. Two Wattson runs on the same bill flagged different discrepancies; both valid, which checks ran varied per invocation. The bridge’s rule: checks are deterministic code, run in full, and the model writes the explanation and plans the detour - never the other way round.
  3. A step cap is a round, not a failure. 13 of 108 runs failed, WorkerStepLimitExceeded on stage. Here a cap ends a round with a case (“not finished: n of m partners checked”), never silently.
Inference cost is irrelevant to the design: a run over 4,883 accounts cost 2.3M tokens and $1.32. What matters is data sovereignty (raised in almost every one of Exnaton’s 20 utility interviews) and the regulatory clock.

Where the bridge stands

In Exnaton’s words, the bridge is “traditional software that knows set paths”: step 3 fails, an event is emitted, a human reads the console. The design below is the detour.

Design rules

Numbered, so the rest of this page and later PRs can cite them.

Target picture

The module: agents/

A new package beside services/, with the same clean split as the rest of the bridge: pure definitions and the run loop in the package, I/O behind adapters with fakes.

The run loop

Only proposals leave the loop; an executed action is a proposal whose approval was the agent’s own autonomy, recorded as such. After every action the agent re-reads the status it acted on (Exnaton’s loop), and a finding that persists past the re-read is a case for a person, not a retry.

Cases

A case is the unit of work an operator sees. Today’s ledgers (Wiedervorlagen, Nachversand-Vormerkungen, Zurückstellungen, Ausnahmen) stay as they are; a case references them and the agent updates them through tools. Three categories of the inbox map directly onto what the bridge distinguishes already: To approve (a proposal waits for a person), For a person (the agent found something it has no tool for: a partner’s question, a contract to sign, a decision), Improvements (the agent proposes a rule or a correction to master data or a contact address - today’s kontakt_adresse_setzen, rahmenvertrag_setzen).

Rules

Rules P31 and P32 are today’s standing_rejections logic, written down where a run can cite it. An operator instruction on a case (“Add to policy: in case of a code 94 rejection of ANFORDERUNG_PT, verify an active membership first”) lands as a proposed rule in Improvements; adopting it is an edit to the agent’s rules by a person with the process key. “Self-learning” in Exnaton’s sense (the agent appends to its own memory) is off by design: memory here is the cases ledger and the rules, both human-owned.

Triggers

The trigger bus is the orchestrator tick’s successor: orchestrate() keeps the heartbeat and the hash-driven day steps (D11) and otherwise becomes “fire what is due”. Each routine it hard-wires today becomes a registered agent run with its trigger, in the same order at first, so PR 2 changes no behaviour.

Autonomy and action policy

Action policy is server-side configuration per tool, as in the operator-app design, and an agent cannot raise it: The last row is the operator-app design’s “never on the phone” list, kept verbatim: an agent is an operator with fewer rights, not more.

The first agents

Each maps onto loops and flags that exist. The flags stay as the migration’s compatibility layer and disappear with PR 2.
Purpose: keep every Netzbetreiber, ÜNB and BIKO exchange of the BKV in a positively acknowledged state, and say early where it will not be.Triggers: aperak_needs_review, contrl_sent, a negative APERAK or CONTRL received (new event), erstkontakt_fanout_retry, partin_failed, zuordnung_failed, bestellung_failed, marktdaten_unbekannt; deadline: APERAK due, Quittungs-Nachfass grace (quittung_nachfass_karenz_stunden) past, MaBiS activation deadline past; schedule: daily sweep over market-partners/overview.Skills: de-mako-quittungen (checks: every received interchange acknowledged in time, every sent file acknowledged or chased, standing rejections per stream), de-mako-registrierung (checks: error 23 and Z29 patterns, Nachversand evidence), de-mabis-aktivierung (checks: activations against expected series, deadlines), de-mako-nachrichten (knowledge: the APERAK, PARTIN, ZOE and Bestellungen pages, the KB’s MaBiS and GPKE processes). Tools: the eleven rows above.Replaces: auto_aperak, auto_answer_partin, auto_nachversand, auto_zoe, and the Nachfass/Korrektur/Stammdaten/Auskunft loops.First step, as in the conference notes: propose-only for a month on real traffic. Measure how many proposals a person would have approved unchanged.

Configuration

An agent definition, as the console’s wizard (Purpose → Skills → Policy & limits → Triggers & behaviour → Review) writes it:
What is configurable and what is not: Everything configurable is a versioned JSON ledger on the audit share, with the same overlay semantics as the runtime configuration: an environment can seed agents at deploy time, the console changes them without a restart, and deleting the overlay reverts.

Skills from the regulatory KB

Exnaton has one hand-written skill per country (“austrian-market- processes”). The KB has 31 scopes with data, DE among them with MaBiS, GPKE, WiM and MPES. Idea 2 of the conference notes packages the KB as loadable skills per scope and process (de-mako-mscons, de-mabis-aperak, ch-sdat-switch, at-eda-eeg), versioned against the source documents. In this design a knowledge skill is a generated file in the skill registry: the process’s goal, steps, deadlines, message types, rejection codes and their meaning, with the KB document and chunk ids it was generated from and the document version. A test fails when the KB’s document version moves and the skill was not regenerated. The same files, exposed over MCP by the bridge, are the “Market Process Skills” the notes propose handing to Exnaton for a DE pilot.

The process API as a tool surface

Partnership option A in the notes is “an API an agent can read state from and write actions to”. The skill registry’s tools are exactly that, and the bridge exposes them as an MCP server under the process scope (read tools and preview tools; execute stays behind the preview/execute path with a key of its own). An external orchestrator - Exnaton’s, SAP Joule’s - then sees the same cases and the same previews an internal agent does, and can approve nothing it could not approve as an operator.

Measuring it

The analytics the inbox needs, per agent and in total, from the cases ledger alone: And one domain figure per agent, the way Exnaton’s billability curve (“96.7 % → 99.79 % since baseline”) carries its case study: Each has a baseline the day the agent goes live, and the console shows the curve since, as the Fahrplan/Ist chart shows deviation today.

What stays as it is

  • The day-ahead pipeline and its hash-based change detection; the orchestrator’s heartbeat; the gate-closure watchdog’s emergency alert (an agent may add context to it, never replace it).
  • EDIFACT generation and parsing, the reference rules, CONTRL and APERAK content, the Bestellungen previews.
  • The event catalog as the public contract, the Slack interaction log, the alerting rules in notify.py. Agent actions are events like any other (case_opened, proposal_made, proposal_approved, action_executed, rule_proposed, rule_adopted, run_failed), cataloged and tested.
  • Scopes and keys. The runner acts under a service identity (agent:<slug>) that appears in api_call events and the audit exactly as a caller.
  • The operator-app design: device keys, preview/execute, four eyes, idempotency, the “never on the phone” list.

Data protection

  • A run receives findings, not the audit share (D10). Each skill declares which fields of a finding may reach the model; partner free text is allowed only for verstehe-antwort, as the classifier sends it today.
  • The model, its region and the processing agreement are configuration (classifier_model becomes per agent; the provider base URL a setting), so EU model operation is a deployment choice.
  • Run logs hold tool calls and results as the bridge saw them, on the audit share, under the same retention as the EDIFACT cache.
  • Nothing the model writes reaches a partner without a person or an explicitly configured autonomy having seen the preview (D2, D3).

Order of work

1

PR 1 - Cases and the inbox, no model

The cases ledger, /v1/process/cases*, the console tab with the six views and the outcome taxonomy. Today’s warnings that already name a subject become cases opened by code: standing rejections, open Wiedervorlagen, gate_closure_warning, forecast_backup_at_trader_deadline, vertragsbefund, fahrplan_vom_uenb_geaendert, marktdaten_unbekannt. Operators close them with an outcome. Result: the taxonomy and the inbox are real before any agent is, and the baseline figures exist.
2

PR 2 - Agent definitions and the trigger bus

The agents/ package, definitions as ledgers, the console wizard, the trigger bus on the event log and the clocks. Every routine in orchestrate() is registered as an agent run with a schedule trigger in today’s order and today’s flag as its autonomy; orchestrate() becomes heartbeat, day steps and “fire what is due”. No behaviour change; the flags are read from the definitions from now on.
3

PR 3 - Tools and previews

The skill registry with the eleven tools, each with preview (the dry run), execute (through the operator-app preview/execute path, extended to the console) and its policy. The functions without a dry run get one, with the “preview sends nothing” test of the app design. Checks for de-mako-quittungen and de-mako-registrierung written as enumerated functions over what the overview and the EDIFACT search return.
4

PR 4 - The runner, Agent 1 in propose-only

adapters/agent_runner.py with the Claude runner and the in-memory fake; the run loop with caps and rounds; the MaKo Exception Handler on real traffic, propose-only, dry run off for reads. A month of proposals against what the operators did. The approval rate decides the next level.
5

PR 5 - Rules and instructions

Shared policy and agent rules as versioned ledgers, rule citations in explanations, Instruct the agent on a case, proposed rules in Improvements, adoption by a person. Analytics tab.
6

PR 6 - Agents 2 and 3, flags retired

Day-ahead watch and partner onboarding; the classifier folded into Agent 3; the auto_* flags removed from Settings in favour of the definitions, with a migration that writes today’s flag values into the seeded definitions.
7

PR 7 - Knowledge skills from the KB, MCP surface

Generated de-* knowledge skills with KB version pins and the drift test; the tool registry exposed over MCP under the process scope. This is the piece that can be handed to a partner.

Open decisions

1

Autonomy ceiling

Should any agent ever reach act for a message to a market partner, or is act_with_approval the permanent ceiling for everything but the deadline-bound APERAK?
2

Who approves

The process key today identifies a role, not a person. Four eyes needs two people; the operator-app design brings named device keys. Is the console’s approval bound to a named console identity (OIDC) before PR 3, or is the app the only four-eyes surface?
3

Gate window

D5 lets a deadline wake an agent inside the gate window; P2 forbids writes there. Should Agent 2 be allowed its customer mail inside the window, or only the Notiz?
4

Model and region

EU model operation for every agent from day one, or only where partner free text is involved (Agent 3)?
5

Rule adoption

Adopting a proposed rule: one person with the process key, or four eyes like a PARTIN resend?
6

Case retention

Cases and run logs: retained like the EDIFACT cache (200 days), or with the audit trail (indefinitely)?
7

Partner skills

Which three knowledge skills are generated first, and which one is offered to Exnaton free for a DE pilot?