docs: separate the two triggers, and put Kafka in the backlog

An earlier revision collapsed detection and ordering into one nightly run.
They are not the same job: detecting a coming stock-out depends on something
happening and should be woken by it, while proposing a purchase order is
genuinely periodic — grouped by supplier lead time, not by unit sold.

Recorded because it changes what has to be built: the autonomous mandate is a
cost of choosing a clock, not of the business need.

Kafka is the target for the reactive half. Nothing in the estate emits a domain
event today, which is what made a nightly sweep look inevitable. Detection stays
unbuilt until then rather than being approximated by a periodic scan — a batch
pretending to be reactive is worse than an absent feature, because it looks
finished.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Stéphane Tailland
2026-08-29 13:46:49 +02:00
parent f49f3ec360
commit 18a8bf38a7
+32 -2
View File
@@ -4,7 +4,7 @@
| Agent | Client id | Trigger | | Agent | Client id | Trigger |
|---|---|---| |---|---|---|
| Approvisionnement | `classic-models-agent-approvisionnement` | nightly | | Approvisionnement | `classic-models-agent-approvisionnement` | event-driven, plus a periodic ordering run |
| Recouvrement | `classic-models-agent-recouvrement` | weekly, Monday | | Recouvrement | `classic-models-agent-recouvrement` | weekly, Monday |
They share a repo because they are not code: n8n workflow exports, same tool, They share a repo because they are not code: n8n workflow exports, same tool,
@@ -26,7 +26,25 @@ They remain full A2A agents: they publish an Agent Card, accept tasks, answer.
| MCP | catalog, sales | | MCP | catalog, sales |
| Scopes | `catalog:read`, `catalog:write`, `sales:read` | | Scopes | `catalog:read`, `catalog:write`, `sales:read` |
Nightly: detect coming stock-outs, propose reorders. Detect coming stock-outs, propose reorders — **two jobs with two different
triggers**, which an earlier revision of this file collapsed into one nightly
run.
*Detection is reactive.* It depends on something happening: an order placed, a
stock level crossing a threshold. Finding that out up to a day later is latency
chosen for nothing, and a nightly sweep re-reads the whole catalog to rediscover
what the domain already knew at the moment it changed.
*Proposing a purchase order is periodic.* Nobody reorders on every unit sold;
orders are grouped by supplier lead time and buying cycle. A clock is the right
trigger there, and that run is periodic on purpose rather than a batch standing
in for events.
Worth naming, because it changes what has to be built: **the autonomous mandate
is a cost of the trigger, not of the business need.** `offline_access`, a
refresh token stored encrypted and an exchange at trigger time are required only
because nobody is present at 3am. An agent woken by a domain event runs moments
after a human acted.
**Exposes** `check_availability` — called by Ventes before promising a delivery **Exposes** `check_availability` — called by Ventes before promising a delivery
date, and by Catalogue before discontinuing a reference. Returns a decision and a date, and by Catalogue before discontinuing a reference. Returns a decision and a
@@ -76,6 +94,18 @@ The MCP servers see no difference between an autonomous and a conversational
call — same `sub`, same `azp`, same audiences. That is deliberate: downstream call — same `sub`, same `azp`, same audiences. That is deliberate: downstream
policy must not need to know the trigger mode. policy must not need to know the trigger mode.
## Backlog
**Events over Kafka.** The target for the reactive half. The estate emits no
domain event today — `classic-models-api` has no signals, no outbound webhook,
and there is no bus in the cluster — so a workflow can only poll, which is what
made a nightly sweep look like the only option. Until Kafka is in place,
detection stays unbuilt rather than being approximated by a periodic scan: a
batch that pretends to be reactive is worse than an absent feature, because it
looks finished.
The periodic ordering run does not wait on this.
## Two controls that become mandatory here ## Two controls that become mandatory here
They were deferrable with a human in the loop. They are not, once an agent They were deferrable with a human in the loop. They are not, once an agent