fix: preserve command effect certainty across retries
Separate per-attempt physical state from the logical execution history. The executor now keeps one monotonic certainty accumulator joined through joinMutationEffectCertainty, records MAYBE_APPLIED at dispatch, and reads the accumulator from every retry-loop fence, final-invariant, cancellation and timeout return. A retry-time scope fence landing between the loop-entry check and the pre-dispatch invariant can no longer downgrade an already dispatched command to NOT_STARTED. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
4e87bacdf3
commit
e06e4377ca
@@ -2,6 +2,7 @@ import { describe, expect, it, vi } from "vitest";
|
||||
|
||||
import { createHttpClient } from "../../src/adapters/http/client.ts";
|
||||
import { createContractHttpExecutor } from "../../src/adapters/http/http-execution-v3.ts";
|
||||
import { joinMutationEffectCertainty } from "../../src/adapters/http/http-effect-certainty.ts";
|
||||
import {
|
||||
entityQueryKeys,
|
||||
TEST_HTTP_CONTRACT,
|
||||
@@ -49,6 +50,22 @@ function testClient(options: HttpDependencies) {
|
||||
return createHttpClient({ ...TEST_HTTP_CONTRACT, ...options });
|
||||
}
|
||||
|
||||
describe("mutation effect certainty lattice", () => {
|
||||
it.each([
|
||||
["NOT_STARTED", "NOT_APPLIED", "NOT_APPLIED"],
|
||||
["NOT_APPLIED", "NOT_STARTED", "NOT_APPLIED"],
|
||||
["NOT_STARTED", "MAYBE_APPLIED", "MAYBE_APPLIED"],
|
||||
["MAYBE_APPLIED", "NOT_STARTED", "MAYBE_APPLIED"],
|
||||
["MAYBE_APPLIED", "NOT_APPLIED", "MAYBE_APPLIED"],
|
||||
["NOT_APPLIED", "MAYBE_APPLIED", "MAYBE_APPLIED"],
|
||||
["MAYBE_APPLIED", "APPLIED_CONFIRMED", "APPLIED_CONFIRMED"],
|
||||
["APPLIED_CONFIRMED", "NOT_STARTED", "APPLIED_CONFIRMED"],
|
||||
["APPLIED_CONFIRMED", "MAYBE_APPLIED", "APPLIED_CONFIRMED"],
|
||||
] as const)("joins %s with %s as %s", (current, observed, expected) => {
|
||||
expect(joinMutationEffectCertainty(current, observed)).toBe(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe("HTTP operation execution contract", () => {
|
||||
it("permits a keyless command intent but rejects an unexpected key before dispatch", async () => {
|
||||
const attachCredentials = vi.fn(() => ({
|
||||
|
||||
Reference in New Issue
Block a user