@indigoai-us/hq-cloud 6.16.66 → 6.16.67

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.
@@ -2075,6 +2075,61 @@ describe("share", () => {
2075
2075
  vi.mocked(uploadFile).mockResolvedValue({ etag: '"upload-etag"' });
2076
2076
  }
2077
2077
  });
2078
+ it("defers a file that vanishes between upload and journal as a diagnostic error", async () => {
2079
+ // Production (2026-09-19 02:02:57Z, agent Alpha, company equi):
2080
+ // workers/thread-police/data/run.lock was PUT, then deleted by the
2081
+ // worker before updateEntry's lstat. PrematureJournalEntryError is
2082
+ // correct (nothing journaled), but the catch used to emit a hard
2083
+ // type:"error" so hq-sync-runner exited 2. Same diagnostic deferral
2084
+ // as a rate-limited PUT; the next pass re-plans the key.
2085
+ const companyRoot = path.join(tmpDir, "companies", "acme");
2086
+ fs.mkdirSync(companyRoot, { recursive: true });
2087
+ const relativePath = "workers/thread-police/data/run.lock";
2088
+ const testFile = path.join(companyRoot, relativePath);
2089
+ fs.mkdirSync(path.dirname(testFile), { recursive: true });
2090
+ fs.writeFileSync(testFile, "pid");
2091
+ const journalPath = path.join(stateDir, "sync-journal.acme.json");
2092
+ seedJournalAt(journalPath, {
2093
+ version: "1",
2094
+ lastSync: new Date(Date.now() - 60_000).toISOString(),
2095
+ files: {},
2096
+ });
2097
+ vi.mocked(uploadFile).mockReset();
2098
+ let putAttempted = false;
2099
+ vi.mocked(uploadFile).mockImplementationOnce(async (_ctx, localPath, key) => {
2100
+ expect(key).toBe(relativePath);
2101
+ putAttempted = true;
2102
+ fs.unlinkSync(localPath);
2103
+ return { etag: '"upload-etag"' };
2104
+ });
2105
+ try {
2106
+ const events = [];
2107
+ const result = await share({
2108
+ paths: [testFile],
2109
+ company: "acme",
2110
+ vaultConfig: mockConfig,
2111
+ hqRoot: tmpDir,
2112
+ onEvent: (e) => events.push(e),
2113
+ });
2114
+ expect(putAttempted).toBe(true);
2115
+ expect(result.filesUploaded).toBe(0);
2116
+ expect(result.filesSkipped).toBeGreaterThanOrEqual(1);
2117
+ expect(journalAt(journalPath).files[relativePath]).toBeUndefined();
2118
+ const errorEvents = events.filter((e) => e.type === "error");
2119
+ expect(errorEvents).toHaveLength(1);
2120
+ expect(errorEvents[0]).toMatchObject({
2121
+ type: "error",
2122
+ diagnostic: true,
2123
+ path: relativePath,
2124
+ message: expect.stringContaining("PrematureJournalEntryError"),
2125
+ });
2126
+ expect(events.some((e) => e.type === "error" && e.diagnostic !== true)).toBe(false);
2127
+ }
2128
+ finally {
2129
+ vi.mocked(uploadFile).mockReset();
2130
+ vi.mocked(uploadFile).mockResolvedValue({ etag: '"upload-etag"' });
2131
+ }
2132
+ });
2078
2133
  it("defers a breaker-tripped upload batch as one diagnostic company error", async () => {
2079
2134
  // Production (2026-09-18 16:03Z brickcraft, 16:05Z mhi-media): the
2080
2135
  // RateLimitBreaker tripped, remaining GET presigns all threw