Repository navigation
Harden distributed writes for work-sdk v0.4 - #3
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7e29ccb53a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (change.action === "update") { | ||
| if (change.changes.length === 0) item = current; | ||
| else { | ||
| mutationStarted = true; |
There was a problem hiding this comment.
Preserve atomic update conflicts
When an Azure DevOps update races with another writer after the client's preflight read, the adapter's JSON Patch /rev test rejects with WorkConflictError before applying any mutation; setting mutationStarted before adapter.update means the catch path below converts that safe atomic conflict into WorkAmbiguousCommitError and marks the idempotency claim ambiguous. Callers then have to reconcile and the key stays blocked even though no provider write succeeded, so atomic update conflicts should remain retryable conflicts instead of being treated as uncertain outcomes.
Useful? React with 👍 / 👎.
| let mutationStarted = false; | ||
| try { | ||
| if (change.action === "create") { | ||
| mutationStarted = true; |
There was a problem hiding this comment.
Keep create preflights from poisoning idempotency keys
For creates, this flag is set before the adapter has finished its own preflight work, so safe validation failures are reported as ambiguous writes. For example, gitlabWorkAdapter.create validates labels before issuing the POST; through WorkClient.commit, an unknown label now throws WorkAmbiguousCommitError and abandons the key as ambiguous even though no issue creation was attempted, leaving callers unable to fix the input and retry the same business key.
Useful? React with 👍 / 👎.
| const normalized = requested.toLowerCase(); | ||
| const canonical = ["backlog", "unstarted", "started", "completed", "canceled", "unknown"].includes(normalized); | ||
| if (!canonical) { | ||
| return [...states.keys()].find((name) => name.toLowerCase() === normalized) ?? requested; |
There was a problem hiding this comment.
Preserve Azure state-name casing
When callers pass a provider-native Azure state that is present in the built-in or custom stateMap, this returns the lower-cased map key instead of the exact state name the caller supplied. For example the docs' Ready for validation custom state is normalized to ready for validation before the JSON Patch is sent, so tenants with cased/custom state names can reject the transition even though the input used the correct provider-native value.
Useful? React with 👍 / 👎.
What changed
get/setrecipe with an atomicacquire/complete/abandonprotocolWhy
Two workers could previously both read an empty durable store and perform the same provider mutation. Several provider state and identity mappings also looked portable but were not safely round-trippable. v0.4 makes those boundaries explicit and blocks blind retries when a provider outcome cannot be proven.
Validation
publintand Are the Types Wrong checks