@indigoai-us/hq-cloud 6.15.83 → 6.15.85

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.
@@ -4842,6 +4842,237 @@ describe("runRunnerWithLoop — event-push wiring", () => {
4842
4842
  await loop;
4843
4843
  }
4844
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
+ });
4845
5076
  it("keeps every event surface off until a result proves maintenance completed", async () => {
4846
5077
  const watcher = makeWatcherStub();
4847
5078
  const sleep = makeSteppableSleep();
@@ -8820,6 +9051,129 @@ describe("runRunnerWithLoop — Phase 3 event-sync wiring (US-017/018/019)", ()
8820
9051
  shutdown();
8821
9052
  await loop;
8822
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
+ });
8823
9177
  it("does not publish unlinkDir when a covered descendant delete was refused", async () => {
8824
9178
  const publishBatch = vi.fn();
8825
9179
  const startEventSync = vi.fn().mockResolvedValue({