@brainervirus/workit-codex 2.2.0 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "workit",
3
- "version": "2.2.0",
3
+ "version": "2.2.1",
4
4
  "description": "Adaptive engineering workflow rails for Codex",
5
5
  "author": {
6
6
  "name": "BrainerVirus"
@@ -16683,7 +16683,7 @@ class TaskStore {
16683
16683
  if (!current.data)
16684
16684
  return failure2("not_found", "workspace not found");
16685
16685
  if (current.data.revision !== expected)
16686
- return this.conflict(expected, current.data.revision);
16686
+ return this.workspaceConflict(expected, current.data.revision);
16687
16687
  const previousBytes = this.snapshotBytes(this.workspacePath);
16688
16688
  if (!previousBytes)
16689
16689
  return failure2("storage_error", "workspace snapshot disappeared during mutation");
@@ -16726,7 +16726,7 @@ class TaskStore {
16726
16726
  if (task.data.revision !== expected)
16727
16727
  return this.conflict(expected, task.data.revision);
16728
16728
  if (workspace.data.revision !== input.expectedWorkspaceRevision)
16729
- return this.conflict(input.expectedWorkspaceRevision, workspace.data.revision);
16729
+ return this.workspaceConflict(input.expectedWorkspaceRevision, workspace.data.revision);
16730
16730
  const previousWorkspaceBytes = this.snapshotBytes(this.workspacePath);
16731
16731
  const previousTaskBytes = this.snapshotBytes(this.taskPath(input.taskId));
16732
16732
  if (!previousWorkspaceBytes || !previousTaskBytes)
@@ -17536,6 +17536,9 @@ class TaskStore {
17536
17536
  actualRevision: actual
17537
17537
  });
17538
17538
  }
17539
+ workspaceConflict(expected, actual) {
17540
+ return failure2("revision_conflict", "workspace revision does not match; omit expectedWorkspaceRevision to use the current record", { expectedWorkspaceRevision: expected, actualWorkspaceRevision: actual });
17541
+ }
17539
17542
  taskPath(taskId) {
17540
17543
  return path4.join(this.tasksDir, `${taskId}.json`);
17541
17544
  }
@@ -20588,6 +20591,29 @@ var applyWorkerLifecycle = (input) => {
20588
20591
  return updated ? success(changed.data.task.revision, changed.data.workspace.revision, updated) : failure2("recovery_required", "worker disappeared during lifecycle observation");
20589
20592
  };
20590
20593
  var refsWithinScope = (refs, scope) => refs.every((ref) => ref.kind !== "file" || bindingCovers(scope, { description: "", paths: [ref.path], exclusions: [] }));
20594
+ var REVISION_RETRY_ATTEMPTS = 8;
20595
+ var retryPause = new Int32Array(new SharedArrayBuffer(4));
20596
+ var filledRevisions = (request) => {
20597
+ const value = typeof request === "object" && request !== null ? request : {};
20598
+ return {
20599
+ task: value.expectedRevision === undefined,
20600
+ workspace: value.expectedWorkspaceRevision === undefined
20601
+ };
20602
+ };
20603
+ var filledConflict = (result, filled) => !result.ok && result.code === "revision_conflict" && (("actualRevision" in result.details) && filled.task || ("actualWorkspaceRevision" in result.details) && filled.workspace);
20604
+ var retryFilledRevisions = (filled, run) => {
20605
+ if (!filled.task && !filled.workspace)
20606
+ return run();
20607
+ let result = run();
20608
+ const deadline = Date.now() + defaultLockTimeout();
20609
+ for (let attempt = 1;filledConflict(result, filled); attempt += 1) {
20610
+ if (attempt >= REVISION_RETRY_ATTEMPTS || Date.now() >= deadline)
20611
+ return failure2("busy", "records kept changing under concurrent writers; retry the call");
20612
+ Atomics.wait(retryPause, 0, 0, Math.floor(Math.random() * 4 * attempt) + 1);
20613
+ result = run();
20614
+ }
20615
+ return result;
20616
+ };
20591
20617
  var trustedNow = (context) => typeof context.now === "function" ? context.now() : context.now;
20592
20618
  var mapRef = (ref, ids) => {
20593
20619
  if (ref.kind !== "record")
@@ -20835,6 +20861,9 @@ class WorkitCore {
20835
20861
  if (input.expectedWorkspaceRevision === undefined)
20836
20862
  input.expectedWorkspaceRevision = workspace ? workspace.revision : null;
20837
20863
  }
20864
+ retryOmittedRevisions(request, run) {
20865
+ return retryFilledRevisions(filledRevisions(request), run);
20866
+ }
20838
20867
  helperEntry(task, requireSession = false, requireActive = false) {
20839
20868
  const workerId = this.context.workerId ?? null;
20840
20869
  if (workerId === null)
@@ -20866,6 +20895,9 @@ class WorkitCore {
20866
20895
  return null;
20867
20896
  }
20868
20897
  state(request) {
20898
+ return request?.action === "import" ? this.retryOmittedRevisions(request, () => this.stateOnce(request)) : this.stateOnce(request);
20899
+ }
20900
+ stateOnce(request) {
20869
20901
  const root = this.contextRootError();
20870
20902
  if (!root.ok)
20871
20903
  return root;
@@ -20967,6 +20999,9 @@ class WorkitCore {
20967
20999
  });
20968
21000
  }
20969
21001
  task(request) {
21002
+ return this.retryOmittedRevisions(request, () => this.taskOnce(request));
21003
+ }
21004
+ taskOnce(request) {
20970
21005
  const root = this.contextRootError();
20971
21006
  if (!root.ok)
20972
21007
  return root;
@@ -21066,6 +21101,9 @@ class WorkitCore {
21066
21101
  }
21067
21102
  }
21068
21103
  policy(request) {
21104
+ return this.retryOmittedRevisions(request, () => this.policyOnce(request));
21105
+ }
21106
+ policyOnce(request) {
21069
21107
  const root = this.contextRootError();
21070
21108
  if (!root.ok)
21071
21109
  return root;
@@ -21112,6 +21150,9 @@ class WorkitCore {
21112
21150
  return success(changed.data.revision, null, changed.data.policy);
21113
21151
  }
21114
21152
  evidence(request) {
21153
+ return this.retryOmittedRevisions(request, () => this.evidenceOnce(request));
21154
+ }
21155
+ evidenceOnce(request) {
21115
21156
  const root = this.contextRootError();
21116
21157
  if (!root.ok)
21117
21158
  return root;
@@ -21196,6 +21237,23 @@ class WorkitCore {
21196
21237
  observeStandingDecision(request) {
21197
21238
  return this.recordDecision(request, undefined, true, true);
21198
21239
  }
21240
+ commitTask(taskId, expected, filled, recheck, update) {
21241
+ let revision = expected;
21242
+ let first = true;
21243
+ return retryFilledRevisions({ task: filled, workspace: false }, () => {
21244
+ if (!first) {
21245
+ const fresh = this.store.readTask(taskId);
21246
+ if (!fresh.ok)
21247
+ return fresh;
21248
+ const checked = recheck(fresh.data);
21249
+ if (!checked.ok)
21250
+ return checked;
21251
+ revision = fresh.data.revision;
21252
+ }
21253
+ first = false;
21254
+ return this.store.mutateTask(taskId, revision, update, trustedNow(this.context));
21255
+ });
21256
+ }
21199
21257
  recordDecision(request, nativeObservation, nativeRequired = false, standing = false) {
21200
21258
  const root = this.contextRootError();
21201
21259
  if (!root.ok)
@@ -21220,6 +21278,7 @@ class WorkitCore {
21220
21278
  return task;
21221
21279
  if ((this.context.workerId ?? null) !== null)
21222
21280
  return failure2("permission_denied", "helpers cannot record or revoke decisions");
21281
+ const filled = input.expectedRevision === undefined;
21223
21282
  this.fillRevisions(input, task.data);
21224
21283
  if (input.action === "record") {
21225
21284
  if (task.data.status === "closed")
@@ -21268,7 +21327,20 @@ class WorkitCore {
21268
21327
  const nativeProvenance = native?.ok ? retireNativeAuthority(native.data) : null;
21269
21328
  if (native?.ok && !nativeProvenance)
21270
21329
  return failure2("permission_denied", "native decision authority was retired");
21271
- const changed = this.store.mutateTask(task.data.id, input.expectedRevision, (current, mutation) => {
21330
+ let standingProvenance = standingApproval?.ok === true ? standingApproval.data : null;
21331
+ const recheck = (fresh) => {
21332
+ if (fresh.status === "closed")
21333
+ return failure2("invalid_transition", "closed task cannot record a decision");
21334
+ if (!standingProvenance)
21335
+ return success(null, null, null);
21336
+ const again = verifyStandingApproval(this.store.root, fresh, this.context.caller, input.binding);
21337
+ if (again.ok)
21338
+ standingProvenance = again.data;
21339
+ return again;
21340
+ };
21341
+ const changed = this.commitTask(task.data.id, input.expectedRevision, filled, recheck, (current, mutation) => {
21342
+ if (current.status === "closed")
21343
+ return failure2("invalid_transition", "closed task cannot record a decision");
21272
21344
  const latestContent = verifyDecisionContent(this.store, input.binding);
21273
21345
  if (!latestContent.ok)
21274
21346
  return latestContent;
@@ -21280,14 +21352,14 @@ class WorkitCore {
21280
21352
  const entry = {
21281
21353
  id: newId(),
21282
21354
  recordedAt: mutation.now,
21283
- provenance: standingApproval?.ok === true ? standingApproval.data : nativeProvenance ?? provenance(this.context, "agent_reported"),
21355
+ provenance: standingProvenance ?? nativeProvenance ?? provenance(this.context, "agent_reported"),
21284
21356
  data
21285
21357
  };
21286
21358
  return success(mutation.revision, null, {
21287
21359
  ...current,
21288
21360
  decisions: [...current.decisions, entry]
21289
21361
  });
21290
- }, trustedNow(this.context));
21362
+ });
21291
21363
  if (!changed.ok)
21292
21364
  return changed;
21293
21365
  return success(changed.data.revision, null, changed.data.decisions.at(-1));
@@ -21301,7 +21373,7 @@ class WorkitCore {
21301
21373
  return failure2("invalid_transition", "decision is already revoked");
21302
21374
  if (decision.data.consumption)
21303
21375
  return failure2("permission_denied", "consumed decision cannot be revoked");
21304
- const changed = this.store.mutateTask(task.data.id, input.expectedRevision, (current, mutation) => {
21376
+ const changed = this.commitTask(task.data.id, input.expectedRevision, filled, () => success(null, null, null), (current, mutation) => {
21305
21377
  const entry = current.decisions.find((candidate) => candidate.id === input.decisionId);
21306
21378
  if (!entry)
21307
21379
  return failure2("not_found", "decision not found");
@@ -21318,13 +21390,16 @@ class WorkitCore {
21318
21390
  ...current,
21319
21391
  decisions: current.decisions.map((candidate) => candidate.id === input.decisionId ? updated : candidate)
21320
21392
  });
21321
- }, trustedNow(this.context));
21393
+ });
21322
21394
  if (!changed.ok)
21323
21395
  return changed;
21324
21396
  const entry = changed.data.decisions.find((candidate) => candidate.id === input.decisionId);
21325
21397
  return entry ? success(changed.data.revision, null, entry) : failure2("recovery_required", "decision disappeared");
21326
21398
  }
21327
21399
  finding(request) {
21400
+ return this.retryOmittedRevisions(request, () => this.findingOnce(request));
21401
+ }
21402
+ findingOnce(request) {
21328
21403
  const root = this.contextRootError();
21329
21404
  if (!root.ok)
21330
21405
  return root;
@@ -21448,6 +21523,9 @@ class WorkitCore {
21448
21523
  return entry ? success(changed.data.revision, null, entry) : failure2("recovery_required", "finding disappeared");
21449
21524
  }
21450
21525
  worker(request) {
21526
+ return this.retryOmittedRevisions(request, () => this.workerOnce(request));
21527
+ }
21528
+ workerOnce(request) {
21451
21529
  const root = this.contextRootError();
21452
21530
  if (!root.ok)
21453
21531
  return root;
@@ -21795,6 +21873,9 @@ class WorkitCore {
21795
21873
  return applied;
21796
21874
  }
21797
21875
  writer(request) {
21876
+ return this.retryOmittedRevisions(request, () => this.writerOnce(request));
21877
+ }
21878
+ writerOnce(request) {
21798
21879
  const root = this.contextRootError();
21799
21880
  if (!root.ok)
21800
21881
  return root;
@@ -100,8 +100,10 @@ values are still concurrency-checked, so never copy revisions between calls.
100
100
  A busy result means another live Workit call holds the checkout lock: retry the
101
101
  same call; it is not a recovery condition. A lock left by a dead process is
102
102
  reclaimed on the next write, and \`workit doctor --fix-lock\` clears it on demand.
103
- A revision_conflict on a call that omitted expectedRevision is contention too:
104
- re-read the record and retry the call.
103
+ An omitted revision absorbs a concurrent write: Workit re-reads, re-checks
104
+ policy, and reapplies the call, returning busy under persistent contention. A
105
+ revision_conflict means a revision you passed is stale: re-read the record
106
+ before deciding whether to retry.
105
107
  A solo edit does not need writer acquisition; use it when concurrent checkout
106
108
  writers need coordination. Record only observed facts and checks. Evidence can
107
109
  become stale when its bound candidate changes; reconcile findings against the
@@ -10658,7 +10660,7 @@ class TaskStore {
10658
10660
  if (!current.data)
10659
10661
  return failure2("not_found", "workspace not found");
10660
10662
  if (current.data.revision !== expected)
10661
- return this.conflict(expected, current.data.revision);
10663
+ return this.workspaceConflict(expected, current.data.revision);
10662
10664
  const previousBytes = this.snapshotBytes(this.workspacePath);
10663
10665
  if (!previousBytes)
10664
10666
  return failure2("storage_error", "workspace snapshot disappeared during mutation");
@@ -10701,7 +10703,7 @@ class TaskStore {
10701
10703
  if (task.data.revision !== expected)
10702
10704
  return this.conflict(expected, task.data.revision);
10703
10705
  if (workspace.data.revision !== input.expectedWorkspaceRevision)
10704
- return this.conflict(input.expectedWorkspaceRevision, workspace.data.revision);
10706
+ return this.workspaceConflict(input.expectedWorkspaceRevision, workspace.data.revision);
10705
10707
  const previousWorkspaceBytes = this.snapshotBytes(this.workspacePath);
10706
10708
  const previousTaskBytes = this.snapshotBytes(this.taskPath(input.taskId));
10707
10709
  if (!previousWorkspaceBytes || !previousTaskBytes)
@@ -11511,6 +11513,9 @@ class TaskStore {
11511
11513
  actualRevision: actual
11512
11514
  });
11513
11515
  }
11516
+ workspaceConflict(expected, actual) {
11517
+ return failure2("revision_conflict", "workspace revision does not match; omit expectedWorkspaceRevision to use the current record", { expectedWorkspaceRevision: expected, actualWorkspaceRevision: actual });
11518
+ }
11514
11519
  taskPath(taskId) {
11515
11520
  return path7.join(this.tasksDir, `${taskId}.json`);
11516
11521
  }
@@ -13398,6 +13403,29 @@ var applyWorkerLifecycle = (input) => {
13398
13403
  return updated ? success(changed.data.task.revision, changed.data.workspace.revision, updated) : failure2("recovery_required", "worker disappeared during lifecycle observation");
13399
13404
  };
13400
13405
  var refsWithinScope = (refs, scope) => refs.every((ref) => ref.kind !== "file" || bindingCovers(scope, { description: "", paths: [ref.path], exclusions: [] }));
13406
+ var REVISION_RETRY_ATTEMPTS = 8;
13407
+ var retryPause = new Int32Array(new SharedArrayBuffer(4));
13408
+ var filledRevisions = (request) => {
13409
+ const value = typeof request === "object" && request !== null ? request : {};
13410
+ return {
13411
+ task: value.expectedRevision === undefined,
13412
+ workspace: value.expectedWorkspaceRevision === undefined
13413
+ };
13414
+ };
13415
+ var filledConflict = (result, filled) => !result.ok && result.code === "revision_conflict" && (("actualRevision" in result.details) && filled.task || ("actualWorkspaceRevision" in result.details) && filled.workspace);
13416
+ var retryFilledRevisions = (filled, run) => {
13417
+ if (!filled.task && !filled.workspace)
13418
+ return run();
13419
+ let result = run();
13420
+ const deadline = Date.now() + defaultLockTimeout();
13421
+ for (let attempt = 1;filledConflict(result, filled); attempt += 1) {
13422
+ if (attempt >= REVISION_RETRY_ATTEMPTS || Date.now() >= deadline)
13423
+ return failure2("busy", "records kept changing under concurrent writers; retry the call");
13424
+ Atomics.wait(retryPause, 0, 0, Math.floor(Math.random() * 4 * attempt) + 1);
13425
+ result = run();
13426
+ }
13427
+ return result;
13428
+ };
13401
13429
  var trustedNow = (context) => typeof context.now === "function" ? context.now() : context.now;
13402
13430
  var mapRef = (ref, ids) => {
13403
13431
  if (ref.kind !== "record")
@@ -13645,6 +13673,9 @@ class WorkitCore {
13645
13673
  if (input.expectedWorkspaceRevision === undefined)
13646
13674
  input.expectedWorkspaceRevision = workspace ? workspace.revision : null;
13647
13675
  }
13676
+ retryOmittedRevisions(request, run) {
13677
+ return retryFilledRevisions(filledRevisions(request), run);
13678
+ }
13648
13679
  helperEntry(task, requireSession = false, requireActive = false) {
13649
13680
  const workerId = this.context.workerId ?? null;
13650
13681
  if (workerId === null)
@@ -13676,6 +13707,9 @@ class WorkitCore {
13676
13707
  return null;
13677
13708
  }
13678
13709
  state(request) {
13710
+ return request?.action === "import" ? this.retryOmittedRevisions(request, () => this.stateOnce(request)) : this.stateOnce(request);
13711
+ }
13712
+ stateOnce(request) {
13679
13713
  const root = this.contextRootError();
13680
13714
  if (!root.ok)
13681
13715
  return root;
@@ -13777,6 +13811,9 @@ class WorkitCore {
13777
13811
  });
13778
13812
  }
13779
13813
  task(request) {
13814
+ return this.retryOmittedRevisions(request, () => this.taskOnce(request));
13815
+ }
13816
+ taskOnce(request) {
13780
13817
  const root = this.contextRootError();
13781
13818
  if (!root.ok)
13782
13819
  return root;
@@ -13876,6 +13913,9 @@ class WorkitCore {
13876
13913
  }
13877
13914
  }
13878
13915
  policy(request) {
13916
+ return this.retryOmittedRevisions(request, () => this.policyOnce(request));
13917
+ }
13918
+ policyOnce(request) {
13879
13919
  const root = this.contextRootError();
13880
13920
  if (!root.ok)
13881
13921
  return root;
@@ -13922,6 +13962,9 @@ class WorkitCore {
13922
13962
  return success(changed.data.revision, null, changed.data.policy);
13923
13963
  }
13924
13964
  evidence(request) {
13965
+ return this.retryOmittedRevisions(request, () => this.evidenceOnce(request));
13966
+ }
13967
+ evidenceOnce(request) {
13925
13968
  const root = this.contextRootError();
13926
13969
  if (!root.ok)
13927
13970
  return root;
@@ -14006,6 +14049,23 @@ class WorkitCore {
14006
14049
  observeStandingDecision(request) {
14007
14050
  return this.recordDecision(request, undefined, true, true);
14008
14051
  }
14052
+ commitTask(taskId, expected, filled, recheck, update) {
14053
+ let revision = expected;
14054
+ let first = true;
14055
+ return retryFilledRevisions({ task: filled, workspace: false }, () => {
14056
+ if (!first) {
14057
+ const fresh = this.store.readTask(taskId);
14058
+ if (!fresh.ok)
14059
+ return fresh;
14060
+ const checked = recheck(fresh.data);
14061
+ if (!checked.ok)
14062
+ return checked;
14063
+ revision = fresh.data.revision;
14064
+ }
14065
+ first = false;
14066
+ return this.store.mutateTask(taskId, revision, update, trustedNow(this.context));
14067
+ });
14068
+ }
14009
14069
  recordDecision(request, nativeObservation, nativeRequired = false, standing = false) {
14010
14070
  const root = this.contextRootError();
14011
14071
  if (!root.ok)
@@ -14030,6 +14090,7 @@ class WorkitCore {
14030
14090
  return task;
14031
14091
  if ((this.context.workerId ?? null) !== null)
14032
14092
  return failure2("permission_denied", "helpers cannot record or revoke decisions");
14093
+ const filled = input.expectedRevision === undefined;
14033
14094
  this.fillRevisions(input, task.data);
14034
14095
  if (input.action === "record") {
14035
14096
  if (task.data.status === "closed")
@@ -14078,7 +14139,20 @@ class WorkitCore {
14078
14139
  const nativeProvenance = native?.ok ? retireNativeAuthority(native.data) : null;
14079
14140
  if (native?.ok && !nativeProvenance)
14080
14141
  return failure2("permission_denied", "native decision authority was retired");
14081
- const changed = this.store.mutateTask(task.data.id, input.expectedRevision, (current, mutation) => {
14142
+ let standingProvenance = standingApproval?.ok === true ? standingApproval.data : null;
14143
+ const recheck = (fresh) => {
14144
+ if (fresh.status === "closed")
14145
+ return failure2("invalid_transition", "closed task cannot record a decision");
14146
+ if (!standingProvenance)
14147
+ return success(null, null, null);
14148
+ const again = verifyStandingApproval(this.store.root, fresh, this.context.caller, input.binding);
14149
+ if (again.ok)
14150
+ standingProvenance = again.data;
14151
+ return again;
14152
+ };
14153
+ const changed = this.commitTask(task.data.id, input.expectedRevision, filled, recheck, (current, mutation) => {
14154
+ if (current.status === "closed")
14155
+ return failure2("invalid_transition", "closed task cannot record a decision");
14082
14156
  const latestContent = verifyDecisionContent(this.store, input.binding);
14083
14157
  if (!latestContent.ok)
14084
14158
  return latestContent;
@@ -14090,14 +14164,14 @@ class WorkitCore {
14090
14164
  const entry = {
14091
14165
  id: newId(),
14092
14166
  recordedAt: mutation.now,
14093
- provenance: standingApproval?.ok === true ? standingApproval.data : nativeProvenance ?? provenance(this.context, "agent_reported"),
14167
+ provenance: standingProvenance ?? nativeProvenance ?? provenance(this.context, "agent_reported"),
14094
14168
  data
14095
14169
  };
14096
14170
  return success(mutation.revision, null, {
14097
14171
  ...current,
14098
14172
  decisions: [...current.decisions, entry]
14099
14173
  });
14100
- }, trustedNow(this.context));
14174
+ });
14101
14175
  if (!changed.ok)
14102
14176
  return changed;
14103
14177
  return success(changed.data.revision, null, changed.data.decisions.at(-1));
@@ -14111,7 +14185,7 @@ class WorkitCore {
14111
14185
  return failure2("invalid_transition", "decision is already revoked");
14112
14186
  if (decision.data.consumption)
14113
14187
  return failure2("permission_denied", "consumed decision cannot be revoked");
14114
- const changed = this.store.mutateTask(task.data.id, input.expectedRevision, (current, mutation) => {
14188
+ const changed = this.commitTask(task.data.id, input.expectedRevision, filled, () => success(null, null, null), (current, mutation) => {
14115
14189
  const entry = current.decisions.find((candidate) => candidate.id === input.decisionId);
14116
14190
  if (!entry)
14117
14191
  return failure2("not_found", "decision not found");
@@ -14128,13 +14202,16 @@ class WorkitCore {
14128
14202
  ...current,
14129
14203
  decisions: current.decisions.map((candidate) => candidate.id === input.decisionId ? updated : candidate)
14130
14204
  });
14131
- }, trustedNow(this.context));
14205
+ });
14132
14206
  if (!changed.ok)
14133
14207
  return changed;
14134
14208
  const entry = changed.data.decisions.find((candidate) => candidate.id === input.decisionId);
14135
14209
  return entry ? success(changed.data.revision, null, entry) : failure2("recovery_required", "decision disappeared");
14136
14210
  }
14137
14211
  finding(request) {
14212
+ return this.retryOmittedRevisions(request, () => this.findingOnce(request));
14213
+ }
14214
+ findingOnce(request) {
14138
14215
  const root = this.contextRootError();
14139
14216
  if (!root.ok)
14140
14217
  return root;
@@ -14258,6 +14335,9 @@ class WorkitCore {
14258
14335
  return entry ? success(changed.data.revision, null, entry) : failure2("recovery_required", "finding disappeared");
14259
14336
  }
14260
14337
  worker(request) {
14338
+ return this.retryOmittedRevisions(request, () => this.workerOnce(request));
14339
+ }
14340
+ workerOnce(request) {
14261
14341
  const root = this.contextRootError();
14262
14342
  if (!root.ok)
14263
14343
  return root;
@@ -14605,6 +14685,9 @@ class WorkitCore {
14605
14685
  return applied;
14606
14686
  }
14607
14687
  writer(request) {
14688
+ return this.retryOmittedRevisions(request, () => this.writerOnce(request));
14689
+ }
14690
+ writerOnce(request) {
14608
14691
  const root = this.contextRootError();
14609
14692
  if (!root.ok)
14610
14693
  return root;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brainervirus/workit-codex",
3
- "version": "2.2.0",
3
+ "version": "2.2.1",
4
4
  "private": false,
5
5
  "description": "Workit Codex CLI/desktop plugin — shared MCP transport, hooks, and fourteen method skills",
6
6
  "keywords": [
@@ -38,8 +38,8 @@
38
38
  "build": "bun scripts/build.ts"
39
39
  },
40
40
  "dependencies": {
41
- "@brainervirus/workit-core": "^2.2.0",
42
- "@brainervirus/workit-mcp": "^2.2.0"
41
+ "@brainervirus/workit-core": "^2.2.1",
42
+ "@brainervirus/workit-mcp": "^2.2.1"
43
43
  },
44
44
  "engines": {
45
45
  "node": ">=24"