@indigoai-us/hq-cloud 6.15.82 → 6.15.84

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.
@@ -4067,6 +4067,238 @@ describe("runRunnerWithLoop — adaptive poll interval (no --poll-remote-ms)", (
4067
4067
  });
4068
4068
  });
4069
4069
  describe("runRunnerWithLoop — event-push wiring", () => {
4070
+ it("parallel coordinator activates every event surface after a partial completed full reconcile", async () => {
4071
+ const previousCoordinator = process.env.HQ_SYNC_PARALLEL_COORDINATOR;
4072
+ const previousEventSync = process.env.HQ_SYNC_EVENT_SYNC;
4073
+ const previousFullReconcileMs = process.env.HQ_SYNC_FULL_RECONCILE_MS;
4074
+ process.env.HQ_SYNC_PARALLEL_COORDINATOR = "1";
4075
+ process.env.HQ_SYNC_EVENT_SYNC = "1";
4076
+ process.env.HQ_SYNC_FULL_RECONCILE_MS = "60000";
4077
+ const watcher = makeWatcherStub();
4078
+ const receiver = {
4079
+ connected: false,
4080
+ start: vi.fn().mockResolvedValue(undefined),
4081
+ dispose: vi.fn().mockResolvedValue(undefined),
4082
+ };
4083
+ const scheduler = {
4084
+ signal: vi.fn(),
4085
+ checkHighWater: vi.fn().mockResolvedValue(undefined),
4086
+ dispose: vi.fn().mockResolvedValue(undefined),
4087
+ };
4088
+ const sleep = makeSteppableSleep();
4089
+ let now = 0;
4090
+ let triggerShutdown = () => { };
4091
+ const createWatcher = vi.fn(() => watcher);
4092
+ const createReceiver = vi.fn(() => receiver);
4093
+ const startRealtimeScheduler = vi.fn().mockResolvedValue(scheduler);
4094
+ const startEventSync = vi.fn().mockResolvedValue(null);
4095
+ const runPass = vi.fn().mockResolvedValue(completedPassOutcome(PARTIAL_SYNC_EXIT));
4096
+ const loop = runRunnerWithLoop(["--companies", "--watch", "--event-push", "--hq-root", "/tmp/hq"], {
4097
+ runPass,
4098
+ createWatcher,
4099
+ createReceiver,
4100
+ startRealtimeScheduler,
4101
+ startEventSync,
4102
+ getIdTokenClaims: () => null,
4103
+ getAccessToken: async () => "jwt-test",
4104
+ monotonicNow: () => now,
4105
+ sleep: sleep.sleep,
4106
+ onShutdownSignal: (handler) => {
4107
+ triggerShutdown = handler;
4108
+ return () => { };
4109
+ },
4110
+ });
4111
+ try {
4112
+ await flushLoopMicrotasks(30);
4113
+ expect(createWatcher).toHaveBeenCalledTimes(1);
4114
+ expect(createReceiver).toHaveBeenCalledTimes(1);
4115
+ expect(receiver.start).toHaveBeenCalledTimes(1);
4116
+ expect(startRealtimeScheduler).toHaveBeenCalledTimes(1);
4117
+ expect(startEventSync).toHaveBeenCalledTimes(1);
4118
+ // A partial RunnerPassOutcome is a completed legacy-equivalent pass, so
4119
+ // its completion must restart the configured full-reconcile cadence.
4120
+ now = 1;
4121
+ sleep.tick();
4122
+ await flushLoopMicrotasks();
4123
+ expect(runPass).toHaveBeenCalledTimes(1);
4124
+ }
4125
+ finally {
4126
+ triggerShutdown();
4127
+ await loop;
4128
+ if (previousCoordinator === undefined)
4129
+ delete process.env.HQ_SYNC_PARALLEL_COORDINATOR;
4130
+ else
4131
+ process.env.HQ_SYNC_PARALLEL_COORDINATOR = previousCoordinator;
4132
+ if (previousEventSync === undefined)
4133
+ delete process.env.HQ_SYNC_EVENT_SYNC;
4134
+ else
4135
+ process.env.HQ_SYNC_EVENT_SYNC = previousEventSync;
4136
+ if (previousFullReconcileMs === undefined)
4137
+ delete process.env.HQ_SYNC_FULL_RECONCILE_MS;
4138
+ else
4139
+ process.env.HQ_SYNC_FULL_RECONCILE_MS = previousFullReconcileMs;
4140
+ }
4141
+ });
4142
+ it("parallel coordinator activates event surfaces and advances cadence after a numeric-zero full reconcile", async () => {
4143
+ const previousCoordinator = process.env.HQ_SYNC_PARALLEL_COORDINATOR;
4144
+ const previousEventSync = process.env.HQ_SYNC_EVENT_SYNC;
4145
+ const previousFullReconcileMs = process.env.HQ_SYNC_FULL_RECONCILE_MS;
4146
+ process.env.HQ_SYNC_PARALLEL_COORDINATOR = "1";
4147
+ process.env.HQ_SYNC_EVENT_SYNC = "1";
4148
+ process.env.HQ_SYNC_FULL_RECONCILE_MS = "60000";
4149
+ const watcher = makeWatcherStub();
4150
+ const receiver = {
4151
+ connected: false,
4152
+ start: vi.fn().mockResolvedValue(undefined),
4153
+ dispose: vi.fn().mockResolvedValue(undefined),
4154
+ };
4155
+ const scheduler = {
4156
+ signal: vi.fn(),
4157
+ checkHighWater: vi.fn().mockResolvedValue(undefined),
4158
+ dispose: vi.fn().mockResolvedValue(undefined),
4159
+ };
4160
+ const sleep = makeSteppableSleep();
4161
+ let now = 0;
4162
+ let triggerShutdown = () => { };
4163
+ const createWatcher = vi.fn(() => watcher);
4164
+ const createReceiver = vi.fn(() => receiver);
4165
+ const startRealtimeScheduler = vi.fn().mockResolvedValue(scheduler);
4166
+ const startEventSync = vi.fn().mockResolvedValue(null);
4167
+ const runPass = vi.fn().mockResolvedValue(0);
4168
+ const loop = runRunnerWithLoop(["--companies", "--watch", "--event-push", "--hq-root", "/tmp/hq"], {
4169
+ runPass,
4170
+ createWatcher,
4171
+ createReceiver,
4172
+ startRealtimeScheduler,
4173
+ startEventSync,
4174
+ getIdTokenClaims: () => null,
4175
+ getAccessToken: async () => "jwt-test",
4176
+ monotonicNow: () => now,
4177
+ sleep: sleep.sleep,
4178
+ onShutdownSignal: (handler) => {
4179
+ triggerShutdown = handler;
4180
+ return () => { };
4181
+ },
4182
+ });
4183
+ try {
4184
+ await flushLoopMicrotasks(30);
4185
+ expect(createWatcher).toHaveBeenCalledTimes(1);
4186
+ expect(createReceiver).toHaveBeenCalledTimes(1);
4187
+ expect(receiver.start).toHaveBeenCalledTimes(1);
4188
+ expect(startRealtimeScheduler).toHaveBeenCalledTimes(1);
4189
+ expect(startEventSync).toHaveBeenCalledTimes(1);
4190
+ // The accepted numeric success seam must advance cadence, preventing an
4191
+ // immediate second full reconcile before the configured interval.
4192
+ now = 1;
4193
+ sleep.tick();
4194
+ await flushLoopMicrotasks();
4195
+ expect(runPass).toHaveBeenCalledTimes(1);
4196
+ }
4197
+ finally {
4198
+ triggerShutdown();
4199
+ await loop;
4200
+ if (previousCoordinator === undefined)
4201
+ delete process.env.HQ_SYNC_PARALLEL_COORDINATOR;
4202
+ else
4203
+ process.env.HQ_SYNC_PARALLEL_COORDINATOR = previousCoordinator;
4204
+ if (previousEventSync === undefined)
4205
+ delete process.env.HQ_SYNC_EVENT_SYNC;
4206
+ else
4207
+ process.env.HQ_SYNC_EVENT_SYNC = previousEventSync;
4208
+ if (previousFullReconcileMs === undefined)
4209
+ delete process.env.HQ_SYNC_FULL_RECONCILE_MS;
4210
+ else
4211
+ process.env.HQ_SYNC_FULL_RECONCILE_MS = previousFullReconcileMs;
4212
+ }
4213
+ });
4214
+ it("parallel coordinator keeps event surfaces off for an auth-required full reconcile", async () => {
4215
+ const previousCoordinator = process.env.HQ_SYNC_PARALLEL_COORDINATOR;
4216
+ const previousEventSync = process.env.HQ_SYNC_EVENT_SYNC;
4217
+ process.env.HQ_SYNC_PARALLEL_COORDINATOR = "1";
4218
+ process.env.HQ_SYNC_EVENT_SYNC = "1";
4219
+ const watcher = makeWatcherStub();
4220
+ const createWatcher = vi.fn(() => watcher);
4221
+ const createReceiver = vi.fn();
4222
+ const startRealtimeScheduler = vi.fn();
4223
+ const startEventSync = vi.fn();
4224
+ let triggerShutdown = () => { };
4225
+ const loop = runRunnerWithLoop(["--companies", "--watch", "--event-push", "--hq-root", "/tmp/hq"], {
4226
+ runPass: vi.fn().mockResolvedValue(AUTH_REQUIRED_PASS_EXIT),
4227
+ createWatcher,
4228
+ createReceiver,
4229
+ startRealtimeScheduler,
4230
+ startEventSync,
4231
+ sleep: () => new Promise(() => { }),
4232
+ onShutdownSignal: (handler) => {
4233
+ triggerShutdown = handler;
4234
+ return () => { };
4235
+ },
4236
+ });
4237
+ try {
4238
+ await flushLoopMicrotasks(30);
4239
+ expect(createWatcher).not.toHaveBeenCalled();
4240
+ expect(createReceiver).not.toHaveBeenCalled();
4241
+ expect(startRealtimeScheduler).not.toHaveBeenCalled();
4242
+ expect(startEventSync).not.toHaveBeenCalled();
4243
+ }
4244
+ finally {
4245
+ triggerShutdown();
4246
+ await loop;
4247
+ if (previousCoordinator === undefined)
4248
+ delete process.env.HQ_SYNC_PARALLEL_COORDINATOR;
4249
+ else
4250
+ process.env.HQ_SYNC_PARALLEL_COORDINATOR = previousCoordinator;
4251
+ if (previousEventSync === undefined)
4252
+ delete process.env.HQ_SYNC_EVENT_SYNC;
4253
+ else
4254
+ process.env.HQ_SYNC_EVENT_SYNC = previousEventSync;
4255
+ }
4256
+ });
4257
+ it("parallel coordinator keeps event surfaces off when no RunnerPassOutcome completed", async () => {
4258
+ const previousCoordinator = process.env.HQ_SYNC_PARALLEL_COORDINATOR;
4259
+ const previousEventSync = process.env.HQ_SYNC_EVENT_SYNC;
4260
+ process.env.HQ_SYNC_PARALLEL_COORDINATOR = "1";
4261
+ process.env.HQ_SYNC_EVENT_SYNC = "1";
4262
+ const watcher = makeWatcherStub();
4263
+ const createWatcher = vi.fn(() => watcher);
4264
+ const createReceiver = vi.fn();
4265
+ const startRealtimeScheduler = vi.fn();
4266
+ const startEventSync = vi.fn();
4267
+ let triggerShutdown = () => { };
4268
+ const loop = runRunnerWithLoop(["--companies", "--watch", "--event-push", "--hq-root", "/tmp/hq"], {
4269
+ // A bare nonzero status represents a chore that did not produce the
4270
+ // post-repair runner outcome needed to prove completion.
4271
+ runPass: vi.fn().mockResolvedValue(PARTIAL_SYNC_EXIT),
4272
+ createWatcher,
4273
+ createReceiver,
4274
+ startRealtimeScheduler,
4275
+ startEventSync,
4276
+ sleep: () => new Promise(() => { }),
4277
+ onShutdownSignal: (handler) => {
4278
+ triggerShutdown = handler;
4279
+ return () => { };
4280
+ },
4281
+ });
4282
+ try {
4283
+ await flushLoopMicrotasks(30);
4284
+ expect(createWatcher).not.toHaveBeenCalled();
4285
+ expect(createReceiver).not.toHaveBeenCalled();
4286
+ expect(startRealtimeScheduler).not.toHaveBeenCalled();
4287
+ expect(startEventSync).not.toHaveBeenCalled();
4288
+ }
4289
+ finally {
4290
+ triggerShutdown();
4291
+ await loop;
4292
+ if (previousCoordinator === undefined)
4293
+ delete process.env.HQ_SYNC_PARALLEL_COORDINATOR;
4294
+ else
4295
+ process.env.HQ_SYNC_PARALLEL_COORDINATOR = previousCoordinator;
4296
+ if (previousEventSync === undefined)
4297
+ delete process.env.HQ_SYNC_EVENT_SYNC;
4298
+ else
4299
+ process.env.HQ_SYNC_EVENT_SYNC = previousEventSync;
4300
+ }
4301
+ });
4070
4302
  it("keeps a healthy watcher through repeated poll cycles and the periodic full reconcile", async () => {
4071
4303
  const sleep = makeSteppableSleep();
4072
4304
  const watchers = [];
@@ -4610,6 +4842,237 @@ describe("runRunnerWithLoop — event-push wiring", () => {
4610
4842
  await loop;
4611
4843
  }
4612
4844
  });
4845
+ it("keeps the parallel watch loop alive after an all-refused warm-up catch-up", async () => {
4846
+ const previousCoordinator = process.env.HQ_SYNC_PARALLEL_COORDINATOR;
4847
+ process.env.HQ_SYNC_PARALLEL_COORDINATOR = "1";
4848
+ const watcher = makeBatchWatcherStub();
4849
+ let markReady = () => { };
4850
+ let shutdown = () => { };
4851
+ let settled;
4852
+ watcher.onReady = (listener) => {
4853
+ markReady = listener;
4854
+ return () => { };
4855
+ };
4856
+ watcher.collectWarmupCatchup = vi.fn(() => ({
4857
+ batch: {
4858
+ paths: new Map([[
4859
+ "/tmp/hq/companies/indigo/warmup-superseded.md",
4860
+ "companies/indigo/warmup-superseded.md",
4861
+ ]]),
4862
+ },
4863
+ scannedPaths: 1,
4864
+ }));
4865
+ let receiverSync;
4866
+ let releaseHeld = () => { };
4867
+ const held = new Promise((resolve) => { releaseHeld = resolve; });
4868
+ const runPass = vi.fn(async (argv) => {
4869
+ if (argv.includes("held.md"))
4870
+ await held;
4871
+ return completedPassOutcome();
4872
+ });
4873
+ const loop = runRunnerWithLoop([
4874
+ "--company", "indigo", "--watch", "--event-push", "--direction", "pull",
4875
+ "--hq-root", "/tmp/hq", "--poll-remote-ms", "60000",
4876
+ ], {
4877
+ runPass,
4878
+ createWatcher: () => watcher,
4879
+ createReceiver: ({ syncBatchFn }) => {
4880
+ receiverSync = syncBatchFn;
4881
+ return { connected: true, start: async () => { }, dispose: async () => { } };
4882
+ },
4883
+ sleep: () => new Promise(() => { }),
4884
+ onShutdownSignal: (handler) => {
4885
+ shutdown = handler;
4886
+ return () => { };
4887
+ },
4888
+ });
4889
+ void loop.then((exitCode) => { settled = exitCode; });
4890
+ try {
4891
+ await flushLoopMicrotasks(30);
4892
+ runPass.mockClear();
4893
+ const heldReceiverWork = receiverSync({
4894
+ events: [{
4895
+ kind: "upsert",
4896
+ relativePath: "companies/indigo/held.md",
4897
+ contentHash: "sha256:remote",
4898
+ mtime: "2026-08-28T01:22:30.000Z",
4899
+ originDeviceId: "peer-device",
4900
+ originTenantId: "tenant-indigo",
4901
+ sequenceNumber: 1,
4902
+ eventTimestamp: "2026-08-28T01:22:30.000Z",
4903
+ }],
4904
+ signal: new AbortController().signal,
4905
+ });
4906
+ await flushLoopMicrotasks();
4907
+ markReady();
4908
+ await flushLoopMicrotasks(30); // queues the warm-up push behind held work
4909
+ const firstReplacement = receiverSync({
4910
+ events: [{
4911
+ kind: "upsert",
4912
+ relativePath: "companies/indigo/warmup-superseded.md",
4913
+ contentHash: "sha256:remote",
4914
+ mtime: "2026-08-28T01:22:31.000Z",
4915
+ originDeviceId: "peer-device",
4916
+ originTenantId: "tenant-indigo",
4917
+ sequenceNumber: 2,
4918
+ eventTimestamp: "2026-08-28T01:22:31.000Z",
4919
+ }],
4920
+ signal: new AbortController().signal,
4921
+ });
4922
+ await flushLoopMicrotasks(30); // queues the warm-up pull behind held work
4923
+ const secondReplacement = receiverSync({
4924
+ events: [{
4925
+ kind: "upsert",
4926
+ relativePath: "companies/indigo/warmup-superseded.md",
4927
+ contentHash: "sha256:remote",
4928
+ mtime: "2026-08-28T01:22:32.000Z",
4929
+ originDeviceId: "peer-device",
4930
+ originTenantId: "tenant-indigo",
4931
+ sequenceNumber: 3,
4932
+ eventTimestamp: "2026-08-28T01:22:32.000Z",
4933
+ }],
4934
+ signal: new AbortController().signal,
4935
+ });
4936
+ await firstReplacement;
4937
+ await flushLoopMicrotasks(30);
4938
+ // Both warm-up passes were superseded while queued behind held realtime
4939
+ // work, so the coordinator never dispatched their executor. They remain
4940
+ // terminal no-ops rather than fabricated exit-1 runner failures.
4941
+ expect(runPass.mock.calls.filter(([argv]) => argv.includes("warmup-superseded.md"))).toHaveLength(0);
4942
+ expect(settled).toBeUndefined();
4943
+ await Promise.resolve();
4944
+ expect(settled).toBeUndefined();
4945
+ releaseHeld();
4946
+ await heldReceiverWork;
4947
+ await secondReplacement;
4948
+ }
4949
+ finally {
4950
+ releaseHeld();
4951
+ shutdown();
4952
+ await loop;
4953
+ if (previousCoordinator === undefined)
4954
+ delete process.env.HQ_SYNC_PARALLEL_COORDINATOR;
4955
+ else
4956
+ process.env.HQ_SYNC_PARALLEL_COORDINATOR = previousCoordinator;
4957
+ }
4958
+ });
4959
+ it("acknowledges superseded receiver work and records refused telemetry", async () => {
4960
+ const previousCoordinator = process.env.HQ_SYNC_PARALLEL_COORDINATOR;
4961
+ process.env.HQ_SYNC_PARALLEL_COORDINATOR = "1";
4962
+ const watcher = makeBatchWatcherStub();
4963
+ let receiverSync;
4964
+ let shutdown = () => { };
4965
+ let releaseHeld = () => { };
4966
+ const held = new Promise((resolve) => { releaseHeld = resolve; });
4967
+ const runPass = vi.fn(async (argv) => {
4968
+ if (argv.includes("held.md"))
4969
+ await held;
4970
+ return completedPassOutcome();
4971
+ });
4972
+ const loop = runRunnerWithLoop(["--companies", "--watch", "--event-push", "--hq-root", "/tmp/hq"], {
4973
+ runPass,
4974
+ createWatcher: () => watcher,
4975
+ createReceiver: ({ syncBatchFn }) => {
4976
+ receiverSync = syncBatchFn;
4977
+ return { connected: true, start: async () => { }, dispose: async () => { } };
4978
+ },
4979
+ sleep: () => new Promise(() => { }),
4980
+ onShutdownSignal: (handler) => {
4981
+ shutdown = handler;
4982
+ return () => { };
4983
+ },
4984
+ });
4985
+ const stderr = vi.spyOn(process.stderr, "write").mockImplementation(() => true);
4986
+ const event = (relativePath) => ({
4987
+ kind: "upsert",
4988
+ relativePath,
4989
+ contentHash: "sha256:remote",
4990
+ mtime: "2026-08-28T01:22:30.000Z",
4991
+ originDeviceId: "peer-device",
4992
+ originTenantId: "tenant-indigo",
4993
+ sequenceNumber: 1,
4994
+ eventTimestamp: "2026-08-28T01:22:30.000Z",
4995
+ });
4996
+ try {
4997
+ await flushLoopMicrotasks(30);
4998
+ runPass.mockClear();
4999
+ const heldReceiverWork = receiverSync({
5000
+ events: [event("companies/indigo/held.md")],
5001
+ signal: new AbortController().signal,
5002
+ });
5003
+ await flushLoopMicrotasks();
5004
+ const superseded = receiverSync({
5005
+ events: [event("companies/indigo/superseded.md")],
5006
+ signal: new AbortController().signal,
5007
+ });
5008
+ await flushLoopMicrotasks();
5009
+ const replacement = receiverSync({
5010
+ events: [event("companies/indigo/superseded.md")],
5011
+ signal: new AbortController().signal,
5012
+ });
5013
+ await expect(superseded).resolves.toBeUndefined();
5014
+ expect(runPass.mock.calls.filter(([argv]) => argv.includes("superseded.md"))).toHaveLength(0);
5015
+ expect(stderr.mock.calls.map(([chunk]) => String(chunk)).join("")).toContain('"event":"sync.realtime.timing","schemaVersion":1,"source":"receiver","direction":"pull","outcome":"refused"');
5016
+ releaseHeld();
5017
+ await heldReceiverWork;
5018
+ await replacement;
5019
+ }
5020
+ finally {
5021
+ releaseHeld();
5022
+ shutdown();
5023
+ await loop;
5024
+ stderr.mockRestore();
5025
+ if (previousCoordinator === undefined)
5026
+ delete process.env.HQ_SYNC_PARALLEL_COORDINATOR;
5027
+ else
5028
+ process.env.HQ_SYNC_PARALLEL_COORDINATOR = previousCoordinator;
5029
+ }
5030
+ });
5031
+ it("still rejects retryable coordinator receiver outcomes", async () => {
5032
+ const previousCoordinator = process.env.HQ_SYNC_PARALLEL_COORDINATOR;
5033
+ process.env.HQ_SYNC_PARALLEL_COORDINATOR = "1";
5034
+ const watcher = makeBatchWatcherStub();
5035
+ let receiverSync;
5036
+ let shutdown = () => { };
5037
+ const runPass = vi.fn(async (argv) => argv.includes("retryable.md") ? 1 : completedPassOutcome());
5038
+ const loop = runRunnerWithLoop(["--companies", "--watch", "--event-push", "--hq-root", "/tmp/hq"], {
5039
+ runPass,
5040
+ createWatcher: () => watcher,
5041
+ createReceiver: ({ syncBatchFn }) => {
5042
+ receiverSync = syncBatchFn;
5043
+ return { connected: true, start: async () => { }, dispose: async () => { } };
5044
+ },
5045
+ sleep: () => new Promise(() => { }),
5046
+ onShutdownSignal: (handler) => {
5047
+ shutdown = handler;
5048
+ return () => { };
5049
+ },
5050
+ });
5051
+ try {
5052
+ await flushLoopMicrotasks(30);
5053
+ await expect(receiverSync({
5054
+ events: [{
5055
+ kind: "upsert",
5056
+ relativePath: "companies/indigo/retryable.md",
5057
+ contentHash: "sha256:remote",
5058
+ mtime: "2026-08-28T01:22:30.000Z",
5059
+ originDeviceId: "peer-device",
5060
+ originTenantId: "tenant-indigo",
5061
+ sequenceNumber: 1,
5062
+ eventTimestamp: "2026-08-28T01:22:30.000Z",
5063
+ }],
5064
+ signal: new AbortController().signal,
5065
+ })).rejects.toThrow("targeted pull failed with exit code 1");
5066
+ }
5067
+ finally {
5068
+ shutdown();
5069
+ await loop;
5070
+ if (previousCoordinator === undefined)
5071
+ delete process.env.HQ_SYNC_PARALLEL_COORDINATOR;
5072
+ else
5073
+ process.env.HQ_SYNC_PARALLEL_COORDINATOR = previousCoordinator;
5074
+ }
5075
+ });
4613
5076
  it("keeps every event surface off until a result proves maintenance completed", async () => {
4614
5077
  const watcher = makeWatcherStub();
4615
5078
  const sleep = makeSteppableSleep();
@@ -8588,6 +9051,129 @@ describe("runRunnerWithLoop — Phase 3 event-sync wiring (US-017/018/019)", ()
8588
9051
  shutdown();
8589
9052
  await loop;
8590
9053
  });
9054
+ it("parallel coordinator publishes only durable watcher paths after a subset is superseded", async () => {
9055
+ const previousCoordinator = process.env.HQ_SYNC_PARALLEL_COORDINATOR;
9056
+ process.env.HQ_SYNC_PARALLEL_COORDINATOR = "1";
9057
+ const publishBatch = vi.fn();
9058
+ const startEventSync = vi.fn().mockResolvedValue({
9059
+ publishBatch,
9060
+ receiver: { start: async () => { }, dispose: async () => { }, connected: true },
9061
+ ownDeviceId: "dev-test",
9062
+ dispose: vi.fn().mockResolvedValue(undefined),
9063
+ });
9064
+ let releaseHeld = () => { };
9065
+ const held = new Promise((resolve) => { releaseHeld = resolve; });
9066
+ const runPass = vi.fn(async (argv) => {
9067
+ if (argv.includes("held.md"))
9068
+ await held;
9069
+ return completedPassOutcome();
9070
+ });
9071
+ const { loop, watcher, clock, shutdown } = runLoop({
9072
+ claims: EMAIL_CLAIMS,
9073
+ startEventSync,
9074
+ runPass,
9075
+ });
9076
+ const heldPath = "companies/indigo/held.md";
9077
+ const supersededPath = "companies/indigo/superseded.md";
9078
+ const durablePath = "companies/indigo/durable.md";
9079
+ try {
9080
+ await microtasks(30);
9081
+ runPass.mockClear();
9082
+ watcher.emit(heldPath, {
9083
+ paths: new Map([[`/tmp/hq/${heldPath}`, heldPath]]),
9084
+ });
9085
+ clock.advance(0);
9086
+ await microtasks(30);
9087
+ watcher.emit(supersededPath, {
9088
+ paths: new Map([
9089
+ [`/tmp/hq/${supersededPath}`, supersededPath],
9090
+ [`/tmp/hq/${durablePath}`, durablePath],
9091
+ ]),
9092
+ });
9093
+ clock.advance(0);
9094
+ await microtasks(30);
9095
+ watcher.emit(supersededPath, {
9096
+ paths: new Map([[`/tmp/hq/${supersededPath}`, supersededPath]]),
9097
+ });
9098
+ clock.advance(0);
9099
+ await microtasks(30);
9100
+ releaseHeld();
9101
+ await microtasks(60);
9102
+ const durableBatch = publishBatch.mock.calls
9103
+ .map(([batch]) => [...batch.paths.values()])
9104
+ .find((paths) => paths.includes(durablePath));
9105
+ expect(durableBatch).toEqual([durablePath]);
9106
+ }
9107
+ finally {
9108
+ releaseHeld();
9109
+ shutdown();
9110
+ await loop;
9111
+ if (previousCoordinator === undefined)
9112
+ delete process.env.HQ_SYNC_PARALLEL_COORDINATOR;
9113
+ else
9114
+ process.env.HQ_SYNC_PARALLEL_COORDINATOR = previousCoordinator;
9115
+ }
9116
+ });
9117
+ it("parallel coordinator publishes nothing for a wholly superseded watcher batch", async () => {
9118
+ const previousCoordinator = process.env.HQ_SYNC_PARALLEL_COORDINATOR;
9119
+ process.env.HQ_SYNC_PARALLEL_COORDINATOR = "1";
9120
+ const publishBatch = vi.fn();
9121
+ const startEventSync = vi.fn().mockResolvedValue({
9122
+ publishBatch,
9123
+ receiver: { start: async () => { }, dispose: async () => { }, connected: true },
9124
+ ownDeviceId: "dev-test",
9125
+ dispose: vi.fn().mockResolvedValue(undefined),
9126
+ });
9127
+ let releaseHeld = () => { };
9128
+ const held = new Promise((resolve) => { releaseHeld = resolve; });
9129
+ const runPass = vi.fn(async (argv) => {
9130
+ if (argv.includes("held.md"))
9131
+ await held;
9132
+ return completedPassOutcome();
9133
+ });
9134
+ const { loop, watcher, clock, shutdown } = runLoop({
9135
+ claims: EMAIL_CLAIMS,
9136
+ startEventSync,
9137
+ runPass,
9138
+ });
9139
+ const heldPath = "companies/indigo/held.md";
9140
+ const supersededPath = "companies/indigo/wholly-superseded.md";
9141
+ try {
9142
+ await microtasks(30);
9143
+ runPass.mockClear();
9144
+ watcher.emit(heldPath, {
9145
+ paths: new Map([[`/tmp/hq/${heldPath}`, heldPath]]),
9146
+ });
9147
+ clock.advance(0);
9148
+ await microtasks(30);
9149
+ watcher.emit(supersededPath, {
9150
+ paths: new Map([[`/tmp/hq/${supersededPath}`, supersededPath]]),
9151
+ });
9152
+ clock.advance(0);
9153
+ await microtasks(30);
9154
+ watcher.emit(supersededPath, {
9155
+ paths: new Map([[`/tmp/hq/${supersededPath}`, supersededPath]]),
9156
+ });
9157
+ clock.advance(0);
9158
+ await microtasks(30);
9159
+ expect(runPass.mock.calls.filter(([argv]) => argv.includes("wholly-superseded.md"))).toHaveLength(0);
9160
+ expect(publishBatch).not.toHaveBeenCalled();
9161
+ let loopExited = false;
9162
+ void loop.then(() => { loopExited = true; });
9163
+ await microtasks();
9164
+ expect(loopExited).toBe(false);
9165
+ }
9166
+ finally {
9167
+ releaseHeld();
9168
+ await microtasks(30);
9169
+ shutdown();
9170
+ await loop;
9171
+ if (previousCoordinator === undefined)
9172
+ delete process.env.HQ_SYNC_PARALLEL_COORDINATOR;
9173
+ else
9174
+ process.env.HQ_SYNC_PARALLEL_COORDINATOR = previousCoordinator;
9175
+ }
9176
+ });
8591
9177
  it("does not publish unlinkDir when a covered descendant delete was refused", async () => {
8592
9178
  const publishBatch = vi.fn();
8593
9179
  const startEventSync = vi.fn().mockResolvedValue({