A checkout times out after the payment commits. The caller receives no acknowledgement.
Retrying can charge the customer twice. Stopping can leave a completed payment unresolved.
EffectBound makes that recovery decision inspectable through one FalkorDB relationship.
The decision is one edge
An operation points to its contract version. That version points to a recovery policy through a REQUIRES edge:
MATCH (:operation {id: $operation_id})-[:BOUND_TO]->(:contract_version)-[req:REQUIRES]->(:policy)
RETURN req.policy_action
The returned property selects reconcile, complete, or stop.
The local screen prints the query and deciding edge. A separate counter, which the product cannot modify, checks the resulting store state. A healthy database connection alone does not establish recovery.
Change the edge. Observe the consequence.
On 17 October 2026, the local screen recorded:
| Intervention | Screen result | Counter |
|---|---|---|
Policy action set to reconcile
|
REQUIRES reconcile |
match |
Only that property changed to stop
|
REQUIRES stop |
match |
| FalkorDB container stopped | halt |
No recovered flag |
The useful experiment was changing one property while keeping the checkout the same. It made the connection between stored policy and observed behavior visible.
Two further cases checked what happened after context changed:
- A contract-version change left the stored outcome visible; the retry executed nothing.
- An owner update expired approval, left the outcome visible, and the retry executed nothing.
The baseline tied
A reconciler given the same action selected reconcile for the lost acknowledgement, then stop after the contract edit.
The graph selected the same actions. Both cases produced one row and counter match; the reconciler inserted nothing.
That is a tie. These cases establish inspectability, not an advantage over the reconciler.
The receipts include the failures
The local load run used 5,000 then 50,000 nodes, with 50 sessions. Recorded p95 was approximately 3.5026 ms, with an error rate of 0.
Two boundaries remained:
Tenant isolation depended on application code. Filtered recall hid other-tenant data, but an unfiltered query returned tenant-0.
The claim was not atomic. It read the session, then updated it in a second query. Both claim calls returned claimed true. Serializing writes did not make that two-query sequence atomic.
These limitations remain part of the submitted evidence at commit 7cbb048.
What I learned
Start with an observable failure: the effect happened, but the acknowledgement disappeared. Then test the decisions and resulting state separately.
Keep failed experiments in the receipt. A fast query does not establish tenant isolation. Two successful claim responses do not establish exclusive ownership. A baseline tie does not establish superiority.
No 60-case comparison or 15-point memory improvement was measured. The product called no provider model; pins.py records not-called. Coding assistants wrote and checked the workspace code.
The run used falkordb/falkordb pinned to:
sha256:107455e862a824e45e8e9f5a7fbfdf5e00a08b14e13eae2577c72fd9e3f59ba6
Setup and the graph query are in the EffectBound repository.
This is a local prototype. Its contribution is a recovery decision a reviewer can inspect, change, and check against an independent counter.
Top comments (0)