diff --git a/CLAUDE.md b/CLAUDE.md index c70e6b9..8cc0c4f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,7 +4,7 @@ | 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 | 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 | | 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 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 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 They were deferrable with a human in the loop. They are not, once an agent