@indigoai-us/hq-cloud 6.15.79 → 6.15.81

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.
Files changed (100) hide show
  1. package/dist/bin/area-ledger-migration.d.ts +13 -0
  2. package/dist/bin/area-ledger-migration.d.ts.map +1 -0
  3. package/dist/bin/area-ledger-migration.js +64 -0
  4. package/dist/bin/area-ledger-migration.js.map +1 -0
  5. package/dist/bin/area-ledger-migration.test.d.ts +2 -0
  6. package/dist/bin/area-ledger-migration.test.d.ts.map +1 -0
  7. package/dist/bin/area-ledger-migration.test.js +55 -0
  8. package/dist/bin/area-ledger-migration.test.js.map +1 -0
  9. package/dist/bin/sync-runner-company.d.ts +6 -0
  10. package/dist/bin/sync-runner-company.d.ts.map +1 -1
  11. package/dist/bin/sync-runner-company.js +21 -0
  12. package/dist/bin/sync-runner-company.js.map +1 -1
  13. package/dist/bin/sync-runner-company.test.js +112 -0
  14. package/dist/bin/sync-runner-company.test.js.map +1 -1
  15. package/dist/bin/sync-runner-events.test.js +20 -0
  16. package/dist/bin/sync-runner-events.test.js.map +1 -1
  17. package/dist/bin/sync-runner-watch-loop.d.ts +7 -0
  18. package/dist/bin/sync-runner-watch-loop.d.ts.map +1 -1
  19. package/dist/bin/sync-runner-watch-loop.js +308 -20
  20. package/dist/bin/sync-runner-watch-loop.js.map +1 -1
  21. package/dist/bin/sync-runner.d.ts +5 -0
  22. package/dist/bin/sync-runner.d.ts.map +1 -1
  23. package/dist/bin/sync-runner.js.map +1 -1
  24. package/dist/bin/sync-runner.test.js +144 -1
  25. package/dist/bin/sync-runner.test.js.map +1 -1
  26. package/dist/cli/share.d.ts +8 -0
  27. package/dist/cli/share.d.ts.map +1 -1
  28. package/dist/cli/share.js +213 -15
  29. package/dist/cli/share.js.map +1 -1
  30. package/dist/cli/share.test.js +461 -31
  31. package/dist/cli/share.test.js.map +1 -1
  32. package/dist/cli/sync.d.ts +30 -0
  33. package/dist/cli/sync.d.ts.map +1 -1
  34. package/dist/cli/sync.js +83 -8
  35. package/dist/cli/sync.js.map +1 -1
  36. package/dist/cli/sync.test.js +224 -0
  37. package/dist/cli/sync.test.js.map +1 -1
  38. package/dist/cli/watch-event-push-conflict.test.js +22 -11
  39. package/dist/cli/watch-event-push-conflict.test.js.map +1 -1
  40. package/dist/journal-store.test.js +42 -1
  41. package/dist/journal-store.test.js.map +1 -1
  42. package/dist/journal.d.ts +12 -1
  43. package/dist/journal.d.ts.map +1 -1
  44. package/dist/journal.js +103 -6
  45. package/dist/journal.js.map +1 -1
  46. package/dist/s3.d.ts +62 -0
  47. package/dist/s3.d.ts.map +1 -1
  48. package/dist/s3.js +91 -1
  49. package/dist/s3.js.map +1 -1
  50. package/dist/s3.rename-retry.test.d.ts +2 -0
  51. package/dist/s3.rename-retry.test.d.ts.map +1 -0
  52. package/dist/s3.rename-retry.test.js +153 -0
  53. package/dist/s3.rename-retry.test.js.map +1 -0
  54. package/dist/sync/area-ledger-migration.d.ts +116 -0
  55. package/dist/sync/area-ledger-migration.d.ts.map +1 -0
  56. package/dist/sync/area-ledger-migration.js +505 -0
  57. package/dist/sync/area-ledger-migration.js.map +1 -0
  58. package/dist/sync/area-ledger-migration.test.d.ts +2 -0
  59. package/dist/sync/area-ledger-migration.test.d.ts.map +1 -0
  60. package/dist/sync/area-ledger-migration.test.js +274 -0
  61. package/dist/sync/area-ledger-migration.test.js.map +1 -0
  62. package/dist/sync/feature-flags.d.ts +9 -0
  63. package/dist/sync/feature-flags.d.ts.map +1 -1
  64. package/dist/sync/feature-flags.js +19 -0
  65. package/dist/sync/feature-flags.js.map +1 -1
  66. package/dist/sync/feature-flags.test.js +11 -1
  67. package/dist/sync/feature-flags.test.js.map +1 -1
  68. package/dist/sync/index.d.ts +2 -0
  69. package/dist/sync/index.d.ts.map +1 -1
  70. package/dist/sync/index.js +1 -0
  71. package/dist/sync/index.js.map +1 -1
  72. package/dist/sync/parallel-sync-coordinator.d.ts.map +1 -1
  73. package/dist/sync/parallel-sync-coordinator.js +19 -4
  74. package/dist/sync/parallel-sync-coordinator.js.map +1 -1
  75. package/dist/sync/parallel-sync-coordinator.test.js +59 -0
  76. package/dist/sync/parallel-sync-coordinator.test.js.map +1 -1
  77. package/dist/sync/reconcile-cursor.d.ts +97 -0
  78. package/dist/sync/reconcile-cursor.d.ts.map +1 -0
  79. package/dist/sync/reconcile-cursor.js +215 -0
  80. package/dist/sync/reconcile-cursor.js.map +1 -0
  81. package/dist/sync/reconcile-cursor.test.d.ts +2 -0
  82. package/dist/sync/reconcile-cursor.test.d.ts.map +1 -0
  83. package/dist/sync/reconcile-cursor.test.js +139 -0
  84. package/dist/sync/reconcile-cursor.test.js.map +1 -0
  85. package/dist/sync/state-store.d.ts +37 -0
  86. package/dist/sync/state-store.d.ts.map +1 -1
  87. package/dist/sync/state-store.js +109 -1
  88. package/dist/sync/state-store.js.map +1 -1
  89. package/dist/sync/sync-work.d.ts +2 -1
  90. package/dist/sync/sync-work.d.ts.map +1 -1
  91. package/dist/sync/sync-work.js.map +1 -1
  92. package/dist/types.d.ts +6 -0
  93. package/dist/types.d.ts.map +1 -1
  94. package/dist/vault-client.d.ts +9 -2
  95. package/dist/vault-client.d.ts.map +1 -1
  96. package/dist/vault-client.js +3 -2
  97. package/dist/vault-client.js.map +1 -1
  98. package/dist/vault-client.test.js +26 -0
  99. package/dist/vault-client.test.js.map +1 -1
  100. package/package.json +3 -2
@@ -12,6 +12,7 @@ import { type CompanyTombstone } from "./tombstones.js";
12
12
  import { type ScopePrefixInput } from "../prefix-coalesce.js";
13
13
  import { type TransferSemaphore } from "../sync-core.js";
14
14
  import { type RegisterCompanySkillResult } from "../vault-client.js";
15
+ import { type ReconcileApplyCheckpoint } from "../sync/reconcile-cursor.js";
15
16
  /**
16
17
  * Local-only ephemeral artifacts: conflict-side files written whenever a
17
18
  * 3-way merge preserves the displaced side for inspection. Depending on the
@@ -446,6 +447,11 @@ export interface ShareOptions {
446
447
  * the network. See the consult in the Stage-2 classification pass.
447
448
  */
448
449
  fileTombstones?: ReadonlyMap<string, CompanyTombstone>;
450
+ /**
451
+ * Opt-in bounded reconcile apply checkpoint. It is recorded only after
452
+ * `finalizeShareJournal()` has durably committed this slice's outcomes.
453
+ */
454
+ reconcileApply?: ReconcileApplyCheckpoint;
449
455
  /**
450
456
  * What to do when a path the caller EXPLICITLY named cannot be shipped —
451
457
  * it does not resolve under any base, or it resolves outside the company
@@ -481,6 +487,8 @@ export interface CompanySkillRegistrationRequest {
481
487
  companySlug: string;
482
488
  path: string;
483
489
  content: string;
490
+ /** These exact bytes have successfully landed in the company vault. */
491
+ landed?: boolean;
484
492
  }
485
493
  export type CompanySkillRegistrar = (input: CompanySkillRegistrationRequest) => Promise<RegisterCompanySkillResult>;
486
494
  export declare class UnregisteredCompanySkillError extends Error {
@@ -1 +1 @@
1
- {"version":3,"file":"share.d.ts","sourceRoot":"","sources":["../../src/cli/share.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"share.d.ts","sourceRoot":"","sources":["../../src/cli/share.ts"],"names":[],"mappings":"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"}
package/dist/cli/share.js CHANGED
@@ -10,7 +10,7 @@ import * as path from "path";
10
10
  import { resolveEntityContext, isExpiringSoon, refreshEntityContext } from "../context.js";
11
11
  import { createSyncProgressRecorder } from "../sync-progress.js";
12
12
  import { localPathForVaultKey, vaultKeyForLocalPath } from "../local-path-codec.js";
13
- import { uploadFile, uploadSymlink, toPosixKey, headRemoteFile, readVerifiedRemoteSymlinkTarget, deleteRemoteFile, downloadFile, primeObjectTransport, primeUploads, WindowsSymlinkPrivilegeError, WINDOWS_SYMLINK_PRIVILEGE_REMEDY, } from "../s3.js";
13
+ import { uploadFile, uploadSymlink, toPosixKey, headRemoteFile, readVerifiedRemoteSymlinkTarget, deleteRemoteFile, downloadFile, primeObjectTransport, primeUploads, WindowsSymlinkPrivilegeError, WINDOWS_SYMLINK_PRIVILEGE_REMEDY, WindowsRenameBlockedError, WINDOWS_RENAME_BLOCKED_REMEDY, renameOrRaiseWindowsBlocked, } from "../s3.js";
14
14
  import * as crypto from "crypto";
15
15
  import { readJournal, writeJournal, hashFile, hashSymlinkTarget, updateEntry, removeEntry, isTombstone, normalizeEtag, PERSONAL_VAULT_JOURNAL_SLUG, migratePersonalVaultJournal, migrateToV2, } from "../journal.js";
16
16
  import { createIgnoreFilter, hasControlCharacters, isExpectedIgnore, isWithinSizeLimit, } from "../ignore.js";
@@ -26,6 +26,7 @@ import { isCloudAuthoritative } from "../lib/cloud-authoritative.js";
26
26
  import { VaultAuthError, VaultClient, } from "../vault-client.js";
27
27
  import { describeError } from "../lib/describe-error.js";
28
28
  import { readlinkOrNull } from "../lib/readlink-safe.js";
29
+ import { checkpointReconcileApply } from "../sync/reconcile-cursor.js";
29
30
  /**
30
31
  * Push-side fresh-collision convergence probe.
31
32
  *
@@ -686,6 +687,20 @@ export async function share(options) {
686
687
  await executeDeletes(run, plans.deletePlan, plans.decommissionPlan, counters, filesRefusedStalePaths, pathResults, !uploadResult.hadUploadFailure && uploadResult.workerErrors.length === 0);
687
688
  finalizeShareJournal(run);
688
689
  throwUploadWorkerErrors(uploadResult.workerErrors);
690
+ // A reconcile cursor is an all-or-nothing boundary for this bounded apply
691
+ // slice. Upload and delete errors are intentionally reported per-path so an
692
+ // ordinary runner can continue, but none of those retryable outcomes may
693
+ // move the cursor beyond the failed mutation.
694
+ if (!uploadResult.hadUploadFailure &&
695
+ uploadResult.workerErrors.length === 0 &&
696
+ !pathResults.some((result) => result.status === "refused")) {
697
+ checkpointReconcileApply(options.reconcileApply, [
698
+ ...plans.pushPlan.items.map((item) => item.relativePath),
699
+ ...plans.deletePlan.toDelete.map((item) => item.key),
700
+ ...plans.deletePlan.toTombstone,
701
+ ...plans.decommissionPlan,
702
+ ]);
703
+ }
689
704
  return buildShareResult(run, counters, filesRefusedStalePaths, conflictPaths, pathResults, false);
690
705
  }
691
706
  /**
@@ -899,7 +914,11 @@ function skillRegistrarForRun(run) {
899
914
  if (!run.vaultConfig)
900
915
  return undefined;
901
916
  const client = new VaultClient(run.vaultConfig);
902
- return ({ companySlug, path: skillPath, content }) => client.registerCompanySkill(companySlug, { path: skillPath, content });
917
+ return ({ companySlug, path: skillPath, content, landed }) => client.registerCompanySkill(companySlug, {
918
+ path: skillPath,
919
+ content,
920
+ ...(landed === true ? { landed: true } : {}),
921
+ });
903
922
  }
904
923
  function assertValidSkillRegistration(result, expectedPath) {
905
924
  const stampedUid = parseRegisteredCompanySkillUid(result.content);
@@ -943,18 +962,106 @@ async function registerOneCompanySkill(run, entry, registrar) {
943
962
  async function preflightCompanySkillIdentities(run, entries) {
944
963
  if (run.options.personalMode === true || run.ctx.uid.startsWith("prs_"))
945
964
  return;
946
- const unstamped = entries.filter((entry) => entry.kind === "file" &&
947
- CANONICAL_COMPANY_SKILL_RE.test(entry.relativePath) &&
948
- !parseRegisteredCompanySkillUid(fs.readFileSync(entry.absolutePath, "utf8")));
949
- if (unstamped.length === 0)
965
+ const canonical = entries.filter((entry) => entry.kind === "file" &&
966
+ CANONICAL_COMPANY_SKILL_RE.test(entry.relativePath));
967
+ const unstamped = canonical.filter((entry) => !parseRegisteredCompanySkillUid(fs.readFileSync(entry.absolutePath, "utf8")));
968
+ const pending = canonical.filter((entry) => {
969
+ const journalEntry = run.journal.files[entry.relativePath];
970
+ return (journalEntry?.skillMetadataPending === true &&
971
+ journalEntry.hash === hashFile(entry.absolutePath));
972
+ });
973
+ if (unstamped.length === 0 && pending.length === 0)
950
974
  return;
951
975
  const registrar = skillRegistrarForRun(run);
952
976
  if (!registrar) {
953
- throw new UnregisteredCompanySkillError(unstamped.map((entry) => entry.relativePath));
977
+ if (unstamped.length > 0) {
978
+ throw new UnregisteredCompanySkillError(unstamped.map((entry) => entry.relativePath));
979
+ }
980
+ return;
954
981
  }
955
982
  for (const entry of unstamped) {
956
983
  await registerOneCompanySkill(run, entry, registrar);
957
984
  }
985
+ for (const entry of pending) {
986
+ const journalEntry = run.journal.files[entry.relativePath];
987
+ run.options.onHeartbeat?.();
988
+ const remote = await headRemoteFile(run.ctx, entry.relativePath);
989
+ if (!remote) {
990
+ // The upload this marker referred to no longer exists. Drop the stale
991
+ // baseline so the normal planner cannot skip the local file as unchanged
992
+ // and will upload it again on this pass.
993
+ delete run.journal.files[entry.relativePath];
994
+ flushShareJournal(run);
995
+ continue;
996
+ }
997
+ if (!journalEntry?.remoteEtag ||
998
+ normalizeEtag(remote.etag) !== normalizeEtag(journalEntry.remoteEtag)) {
999
+ // The successful PUT this marker describes is no longer the live remote
1000
+ // object. Reconcile the current remote bytes instead of stranding the old
1001
+ // marker behind skipUnchanged; the backend independently revalidates this
1002
+ // exact content against S3 before accepting its metadata.
1003
+ // Invalidate the stale baseline before any network work. If recovery
1004
+ // fails, the next pass must still see a real divergence rather than
1005
+ // classifying the local file as unchanged forever.
1006
+ delete run.journal.files[entry.relativePath];
1007
+ flushShareJournal(run);
1008
+ const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "hq-skill-metadata-"));
1009
+ const tempFile = path.join(tempDir, "SKILL.md");
1010
+ try {
1011
+ await downloadFile(run.ctx, entry.relativePath, tempFile);
1012
+ await reconcileLandedCompanySkill(run, entry.relativePath, fs.readFileSync(tempFile, "utf8"));
1013
+ }
1014
+ finally {
1015
+ fs.rmSync(tempDir, { recursive: true, force: true });
1016
+ }
1017
+ continue;
1018
+ }
1019
+ const landedBytes = fs.readFileSync(entry.absolutePath);
1020
+ const landedHash = crypto
1021
+ .createHash("sha256")
1022
+ .update(landedBytes)
1023
+ .digest("hex");
1024
+ if (landedHash !== journalEntry.hash) {
1025
+ // The editor saved after this entry was classified but before the
1026
+ // remote proof returned. Reconcile only the single local snapshot that
1027
+ // produced the journaled upload; the newer edit belongs to the planner.
1028
+ continue;
1029
+ }
1030
+ await reconcileLandedCompanySkill(run, entry.relativePath, landedBytes.toString("utf8"));
1031
+ delete run.journal.files[entry.relativePath]?.skillMetadataPending;
1032
+ checkpointShareJournal(run);
1033
+ }
1034
+ }
1035
+ /**
1036
+ * Reconcile metadata only after the canonical bytes have landed. Identity
1037
+ * reservation happens before upload; tags and other source-authored metadata
1038
+ * must not become authoritative until the S3 write succeeds.
1039
+ */
1040
+ async function reconcileLandedCompanySkill(run, relativePath, content) {
1041
+ if (run.options.personalMode === true ||
1042
+ run.ctx.uid.startsWith("prs_") ||
1043
+ !CANONICAL_COMPANY_SKILL_RE.test(relativePath)) {
1044
+ return;
1045
+ }
1046
+ const registrar = skillRegistrarForRun(run);
1047
+ if (!registrar) {
1048
+ return;
1049
+ }
1050
+ const localUid = parseRegisteredCompanySkillUid(content);
1051
+ if (!localUid) {
1052
+ throw new UnregisteredCompanySkillError([relativePath]);
1053
+ }
1054
+ run.options.onHeartbeat?.();
1055
+ const result = await registrar({
1056
+ companySlug: run.ctx.slug,
1057
+ path: relativePath,
1058
+ content,
1059
+ landed: true,
1060
+ });
1061
+ assertValidSkillRegistration(result, relativePath);
1062
+ if (result.skillUid !== localUid) {
1063
+ throw new Error(`Skill registration returned identity '${result.skillUid}' for '${relativePath}', but the landed file is stamped '${localUid}'.`);
1064
+ }
958
1065
  }
959
1066
  async function buildSharePlans(run) {
960
1067
  const collected = collectFiles(run.paths, run.hqRoot, run.syncRoot, run.shouldSync, {
@@ -1324,12 +1431,41 @@ async function executeUploads(run, pushPlan, counters, conflictPaths) {
1324
1431
  }
1325
1432
  }
1326
1433
  if (freshContentConverged) {
1434
+ // The equality probe is an await boundary. Confirm that the local body
1435
+ // still matches the bytes we proved are already remote before recording
1436
+ // convergence or reconciling source-authored metadata.
1437
+ const afterProbe = refreshUploadItem();
1438
+ if (afterProbe === null)
1439
+ return;
1440
+ if (!uploadBodyMatchesPlan(item, afterProbe)) {
1441
+ await restartForChangedBody(afterProbe);
1442
+ return;
1443
+ }
1444
+ const shouldReconcileSkill = item.kind === "file" &&
1445
+ CANONICAL_COMPANY_SKILL_RE.test(relativePath) &&
1446
+ skillRegistrarForRun(run) !== undefined;
1447
+ const skillBytes = shouldReconcileSkill
1448
+ ? fs.readFileSync(absolutePath)
1449
+ : undefined;
1450
+ if (skillBytes !== undefined &&
1451
+ crypto.createHash("sha256").update(skillBytes).digest("hex") !== localHash) {
1452
+ // The editor saved after the equality proof. Re-run the normal
1453
+ // remote decision for those new bytes rather than claiming they have
1454
+ // already landed and letting their metadata get ahead of S3.
1455
+ const afterSkillRead = refreshUploadItem();
1456
+ if (afterSkillRead === null)
1457
+ return;
1458
+ await restartForChangedBody(afterSkillRead);
1459
+ return;
1460
+ }
1461
+ const skillContent = skillBytes?.toString("utf8");
1327
1462
  const lstat = fs.lstatSync(absolutePath);
1328
1463
  updateEntry(run.journal, relativePath, localHash, lstat.size, "up", absolutePath, {
1329
1464
  remoteEtag: remoteMeta.etag,
1330
1465
  mtimeMs: lstat.mtimeMs,
1331
1466
  ctimeMs: ctimeToStamp(item.kind === "file" ? item.statAtHash : undefined, lstat),
1332
1467
  kind: item.kind,
1468
+ skillMetadataPending: skillContent !== undefined,
1333
1469
  });
1334
1470
  // Same checkpoint contract as an actual upload. After repeated
1335
1471
  // interrupted passes most of a large vault is already present remotely
@@ -1337,6 +1473,14 @@ async function executeUploads(run, pushPlan, counters, conflictPaths) {
1337
1473
  // through performUpload. Without this, that pass could reconcile
1338
1474
  // hundreds of thousands of entries purely in memory, be interrupted,
1339
1475
  // and persist none of them — the exact loop this change exists to end.
1476
+ if (skillContent !== undefined) {
1477
+ // This is the crash-recovery path for a PUT that completed before its
1478
+ // journal row was persisted. Make the retry marker durable before the
1479
+ // registry call so another interruption remains recoverable.
1480
+ flushShareJournal(run);
1481
+ await reconcileLandedCompanySkill(run, relativePath, skillContent);
1482
+ delete run.journal.files[relativePath]?.skillMetadataPending;
1483
+ }
1340
1484
  checkpointShareJournal(run);
1341
1485
  run.emit({ type: "reconciled", path: relativePath, direction: "push" });
1342
1486
  counters.filesSkipped++;
@@ -1437,10 +1581,24 @@ async function executeUploads(run, pushPlan, counters, conflictPaths) {
1437
1581
  const size = isSymlinkUpload ? 0 : lstat.size;
1438
1582
  const mtimeMs = lstat.mtimeMs;
1439
1583
  const ctimeMs = ctimeToStamp(item.kind === "file" ? item.statAtHash : undefined, lstat);
1584
+ // Capture the candidate metadata bytes immediately before uploadFile's
1585
+ // own synchronous read. If an editor saves while the network request is
1586
+ // in flight, the comparison below suppresses reconciliation; that newer
1587
+ // version will upload and reconcile on the next pass.
1588
+ const skillContentAtPut = !isSymlinkUpload && CANONICAL_COMPANY_SKILL_RE.test(relativePath)
1589
+ ? fs.readFileSync(absolutePath, "utf8")
1590
+ : undefined;
1440
1591
  const { etag } = isSymlinkUpload
1441
1592
  ? await uploadSymlink(run.ctx, item.target, relativePath, run.options.author, pc)
1442
1593
  : await uploadFile(run.ctx, absolutePath, relativePath, run.options.author, pc);
1443
- updateEntry(run.journal, relativePath, localHash, size, "up", absolutePath, { remoteEtag: etag, mtimeMs, ctimeMs, kind: item.kind });
1594
+ updateEntry(run.journal, relativePath, localHash, size, "up", absolutePath, {
1595
+ remoteEtag: etag,
1596
+ mtimeMs,
1597
+ ctimeMs,
1598
+ kind: item.kind,
1599
+ skillMetadataPending: skillContentAtPut !== undefined &&
1600
+ skillRegistrarForRun(run) !== undefined,
1601
+ });
1444
1602
  if (run.message) {
1445
1603
  run.journal.files[relativePath] = {
1446
1604
  ...run.journal.files[relativePath],
@@ -1449,9 +1607,25 @@ async function executeUploads(run, pushPlan, counters, conflictPaths) {
1449
1607
  }
1450
1608
  counters.filesUploaded++;
1451
1609
  counters.bytesUploaded += size;
1452
- // Strictly after the PUT returned and the entry was applied, so an
1453
- // interrupted pass can only ever re-upload a file, never skip one.
1454
- checkpointShareJournal(run);
1610
+ // A landed company skill needs a durable retry marker before the registry
1611
+ // call. The ordinary cadence is intentionally sparse for large vaults,
1612
+ // but losing this row can strand tags after a crash between PUT and
1613
+ // reconciliation.
1614
+ if (run.journal.files[relativePath]?.skillMetadataPending === true) {
1615
+ flushShareJournal(run);
1616
+ }
1617
+ else {
1618
+ // Strictly after the PUT returned and the entry was applied, so an
1619
+ // interrupted pass can only ever re-upload a file, never skip one.
1620
+ checkpointShareJournal(run);
1621
+ }
1622
+ if (skillContentAtPut !== undefined &&
1623
+ skillRegistrarForRun(run) !== undefined &&
1624
+ fs.readFileSync(absolutePath, "utf8") === skillContentAtPut) {
1625
+ await reconcileLandedCompanySkill(run, relativePath, skillContentAtPut);
1626
+ delete run.journal.files[relativePath]?.skillMetadataPending;
1627
+ checkpointShareJournal(run);
1628
+ }
1455
1629
  run.emit({
1456
1630
  type: "progress",
1457
1631
  path: relativePath,
@@ -1635,8 +1809,12 @@ async function writePushConflictMirror(run, item, remoteHash, preserved) {
1635
1809
  // `keep` has one meaning in both directions: cloud wins the working
1636
1810
  // name while the displaced local body remains recoverable beside it.
1637
1811
  // Rename first, then reuse the ordinary tested download path for the
1638
- // replacement instead of hand-rolling a swap around an ad-hoc GET.
1639
- fs.renameSync(item.absolutePath, conflictAbs);
1812
+ // replacement instead of hand-rolling a swap around an ad-hoc GET. A
1813
+ // transient Windows sharing violation on the move-aside surfaces as
1814
+ // WindowsRenameBlockedError so the catch below downgrades it to a
1815
+ // deliberate skip; nothing has moved yet, so the skip strands nothing
1816
+ // (Sentry HQ-DESKTOP-54).
1817
+ renameOrRaiseWindowsBlocked(item.absolutePath, conflictAbs);
1640
1818
  localMovedAside = true;
1641
1819
  const downloaded = await downloadFile(run.ctx, item.relativePath, item.absolutePath);
1642
1820
  remoteAdopted = true;
@@ -1691,6 +1869,11 @@ async function writePushConflictMirror(run, item, remoteHash, preserved) {
1691
1869
  localMovedAside = false;
1692
1870
  }
1693
1871
  catch (rollbackErr) {
1872
+ // A rollback failure is NOT a benign skip even when the underlying
1873
+ // rename refusal is transient: the local body has already been moved to
1874
+ // `conflictAbs` and could not be restored, so the original working path
1875
+ // is now absent. Reporting success here would let a later pass read that
1876
+ // absence as a deletion. Keep it on the error channel (Codex PR #436).
1694
1877
  run.emit({
1695
1878
  type: "error",
1696
1879
  path: item.relativePath,
@@ -1702,7 +1885,19 @@ async function writePushConflictMirror(run, item, remoteHash, preserved) {
1702
1885
  throw mirrorErr;
1703
1886
  if (mirrorErr instanceof JournalCheckpointError)
1704
1887
  throw mirrorErr;
1705
- if (mirrorErr instanceof WindowsSymlinkPrivilegeError) {
1888
+ if (mirrorErr instanceof WindowsRenameBlockedError) {
1889
+ // The local move-aside could not complete because a program is holding
1890
+ // the file open. Emit the deliberate skip (never type:"error") so the
1891
+ // push stays complete and the one-shot runner exits 0; nothing was moved
1892
+ // (localMovedAside is false when the preserve rename threw), so the
1893
+ // conflict simply re-fires next pass (Sentry HQ-DESKTOP-54, second path).
1894
+ run.emit({
1895
+ type: "skip-rename-blocked",
1896
+ path: item.relativePath,
1897
+ remedy: WINDOWS_RENAME_BLOCKED_REMEDY,
1898
+ });
1899
+ }
1900
+ else if (mirrorErr instanceof WindowsSymlinkPrivilegeError) {
1706
1901
  // The remote symlink record cannot be materialized to a conflict mirror
1707
1902
  // on this unprivileged Windows host. Emit the deliberate skip (never
1708
1903
  // type:"error") so the push stays complete and the runner exits 0
@@ -1876,7 +2071,7 @@ async function executeDeletes(run, deletePlan, decommissionPlan, counters, files
1876
2071
  run.emit({
1877
2072
  type: "error",
1878
2073
  path: relativePath,
1879
- message: `tombstone unlink failed: ${err instanceof Error ? err.message : String(err)}`,
2074
+ message: `tombstone unlink failed: ${describeError(err)}`,
1880
2075
  });
1881
2076
  continue;
1882
2077
  }
@@ -2295,6 +2490,9 @@ function defaultConsoleLogger(event) {
2295
2490
  else if (event.type === "skip-symlink-privilege") {
2296
2491
  console.warn(` ! ${event.path} skipped — could not create the symbolic link on this Windows host (missing privilege). ${event.remedy}`);
2297
2492
  }
2493
+ else if (event.type === "skip-rename-blocked") {
2494
+ console.warn(` ! ${event.path} skipped — another program on this PC is holding the file open, so HQ could not replace it yet. ${event.remedy}`);
2495
+ }
2298
2496
  else if (event.type === "ignore-excluded") {
2299
2497
  // The "not silent" surface: an ignore rule dropped content that doesn't
2300
2498
  // look like expected build/VCS/cache noise, so it never reached the vault.