Drop the stale-read workaround; the cache is gone

Preferring the event's figure over the read existed only because the catalog
gateway cached reads for 60 seconds. That cache has been removed at the source,
so the read is current and there is no second source of truth to arbitrate.

The crossing context is now appended only while the reference is still below
the threshold — an entry outlives the condition it describes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Stéphane Tailland
2026-08-31 08:31:07 +02:00
parent 245415e7c6
commit c5d17d1d04
2 changed files with 23 additions and 18 deletions
+22 -17
View File
@@ -108,32 +108,37 @@ webhook — its data lives in that workflow and there is no other way in. The no
is `onError: continueRegularOutput`: an availability answer must not depend on
the watchlist being up.
### A dated fact beats an undated read
### A stale read once made it contradict itself
The two figures can disagree, and when they do the **read** is the wrong one.
This was not theoretical — the agent answered, in one sentence:
The agent published this, in one sentence:
```
"68 in stock, above the reorder threshold of 50 … It crossed the threshold, from 68."
```
The catalog domain caches reads for **60 seconds**. An agent woken by an event
reacts in seconds and then reads a figure taken up to a minute earlier. A
movement is the catalog's own *dated* statement that stock went from X to Y; a
read is an undated copy. So the movement wins, and the answer says the basis
changed:
Both halves were internally consistent and the answer was wrong. The catalog
domain was caching reads for **60 seconds** at the gateway, so an agent woken by
an event read the figure from before the event.
```
Basis: the latest stock movement, which is more recent than the catalog read
```
The first fix was in this workflow — prefer the event's dated figure over the
undated read. It has been **removed**, because the cache was removed instead:
caching a read-write API buys little and costs correctness on every mutable
resource, since the gateway has no invalidation on write. Working around it here
would have left four other domains lying to whatever reads them next.
Measured after the fix, with the cache deliberately warmed at 38 and the true
stock moved to 8 inside the window: the answer said **8**.
Measured after: a `PATCH` to 300 followed three seconds later by the same
question answers **300**.
This only helps a reference the reactive half is already watching. For any
other, the read stands with whatever staleness it has, and nothing in the
workflow can tell — which is worth remembering before treating any single read
as current.
The lesson worth keeping is not about caches. **Do not treat a single read as
current unless something guarantees it** — and an agent cannot tell.
### The crossing is mentioned only while it still holds
An entry stays on the watchlist until a human clears it, so a reference that has
since been restocked still has one. Saying "300 in stock … it crossed the
threshold, from 68" reads as a contradiction even though both halves are true,
so the context is appended only while the reference is actually below the
threshold.
## approvisionnement-periodic-reorder