From 411086b0b6d1fee1bbb948cbc327c1f1fb88d3c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Tailland?= Date: Wed, 26 Aug 2026 15:14:41 +0200 Subject: [PATCH] Add implementation instructions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Design agreed in discussion, nothing built yet. Records the agent's role, its scopes and MCP servers, its A2A surface, and the framework choice with its reason — so the next session starts from the decisions rather than re-deriving them. Co-Authored-By: Claude Opus 5 --- CLAUDE.md | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..c70e6b9 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,101 @@ +# Flows — the autonomous agents + +**Runtime:** n8n · **Mode:** autonomous · Two agents in one repo. + +| Agent | Client id | Trigger | +|---|---|---| +| Approvisionnement | `classic-models-agent-approvisionnement` | nightly | +| Recouvrement | `classic-models-agent-recouvrement` | weekly, Monday | + +They share a repo because they are not code: n8n workflow exports, same tool, +same owner. Splitting them would buy nothing. + +## Why low-code for these two + +Their work is rules, thresholds and due dates — a sequence of conditions and +calls, which a visual editor expresses better than code. The LLM is optional on +their critical path, which makes them cheaper and more predictable than the +conversational agents. + +They remain full A2A agents: they publish an Agent Card, accept tasks, answer. + +## Approvisionnement + +| | | +|---|---| +| MCP | catalog, sales | +| Scopes | `catalog:read`, `catalog:write`, `sales:read` | + +Nightly: detect coming stock-outs, propose reorders. + +**Exposes** `check_availability` — called by Ventes before promising a delivery +date, and by Catalogue before discontinuing a reference. Returns a decision and a +date, never the stock table. + +## Recouvrement + +| | | +|---|---| +| MCP | customers, payments | +| Scopes | `customers:read`, `payments:read`, `payments:write` | + +Weekly: unpaid invoices past 30 days, dunning, escalation. + +**Exposes** `check_creditworthiness` — called by Ventes before accepting a large +order. + +**Dunning is prepared automatically and sent only after human validation.** +Sending a letter to a customer is an outward-facing action; a rule bug would +otherwise write to the entire customer base in one run. + +## The A2A server gap + +The available n8n community nodes ([n8n-nodes-a2a](https://github.com/agentic-layer/n8n-nodes-a2a), +[n8n-nodes-agent2agent](https://github.com/pjawz/n8n-nodes-agent2agent)) make n8n +an A2A **client**: `Discover Agent`, `Send Task`. + +But both agents here must be **servers** — Ventes calls them. That needs an +Agent Card on `/.well-known/agent.json` and a JSON-RPC endpoint with the task +lifecycle. n8n webhooks can do it by hand, at which point it stops being no-code. + +Preferred approach: **Kong in front of n8n**, exactly as it fronts every other +resource. Kong serves the Agent Card statically and routes JSON-RPC to the +webhook, and token verification lands where it already lives. No new component. + +Alternative: a small FastA2A adapter, written once for both — see +`classic-models-agent-catalogue`, which uses FastA2A already. + +## The autonomous mandate + +No user session exists when these run, so authority must be pre-established: the +user obtains `offline_access` when creating the mandate, the refresh token is +stored encrypted, and the exchange happens at trigger time. `sub` stays the user +who mandated, `azp` says which agent acted. + +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. + +## Two controls that become mandatory here + +They were deferrable with a human in the loop. They are not, once an agent +loops on its own. + +- **Read volume caps per `(azp, sub)`**, enforced on Kong. An agent reads a + thousand records in seconds where a human clicks ten; a scope authorises the + read but says nothing about volume. +- **Authorisation on tool-call parameters**, not just the tool name. `write` + authorises writing, not "this €40k transfer". + +An autonomous agent hitting a rule that requires approval must **fail cleanly +and escalate**, never decide. And any approval screen must be rendered from the +structured tool-call parameters — never from a sentence the model produced, or a +prompt injection writes what the human validates. + +## Before writing workflows + +Read `classic-models-agent-platform/CLAUDE.md` for the identity model, the +endpoints and the known blockers. + +Deliverables in English. Export workflows as JSON and commit them; do not rely +on the n8n instance as the source of truth.