@hardkas/core 0.7.3-alpha → 0.7.5-alpha

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.
package/dist/index.d.ts CHANGED
@@ -654,6 +654,7 @@ interface RuntimeContext {
654
654
  random: DeterministicRandom;
655
655
  ids: IdProvider;
656
656
  telemetry: TelemetryManager;
657
+ workflowId?: string;
657
658
  }
658
659
  /**
659
660
  * A default system runtime context (for non-deterministic contexts like dev server or CLI entry points)
@@ -786,7 +787,7 @@ declare class AppendCoordinator {
786
787
  };
787
788
  }
788
789
 
789
- declare const CURRENT_RUNTIME_VERSION = "0.7.3-alpha";
790
+ declare const CURRENT_RUNTIME_VERSION = "0.7.5-alpha";
790
791
  declare const MIN_SUPPORTED_VERSION = "0.5.0-alpha";
791
792
  interface MigrationStatus {
792
793
  needsMigration: boolean;
package/dist/index.js CHANGED
@@ -93,7 +93,13 @@ function getTelemetry() {
93
93
  }
94
94
  var TelemetryProxy = class {
95
95
  logAnomaly(anomalyType, severity, subsystem, details, sandboxOverride) {
96
- return getTelemetry().logAnomaly(anomalyType, severity, subsystem, details, sandboxOverride);
96
+ return getTelemetry().logAnomaly(
97
+ anomalyType,
98
+ severity,
99
+ subsystem,
100
+ details,
101
+ sandboxOverride
102
+ );
97
103
  }
98
104
  init(rootDir) {
99
105
  return getTelemetry().init(rootDir);
@@ -142,7 +148,9 @@ var AppendCoordinator = class _AppendCoordinator {
142
148
  } catch (e) {
143
149
  if (e.code === "EEXIST") {
144
150
  if (Date.now() - start > timeoutMs) {
145
- throw new Error(`[AppendCoordinator] Timeout waiting for lock on ${lockPath}`);
151
+ throw new Error(
152
+ `[AppendCoordinator] Timeout waiting for lock on ${lockPath}`
153
+ );
146
154
  }
147
155
  const sleepMs = 5 + Math.floor(Math.random() * 15);
148
156
  const sharedBuf = new Int32Array(new SharedArrayBuffer(4));
@@ -152,7 +160,10 @@ var AppendCoordinator = class _AppendCoordinator {
152
160
  throw e;
153
161
  }
154
162
  }
155
- fs.writeSync(fd, JSON.stringify({ pid: process.pid, time: (/* @__PURE__ */ new Date()).toISOString() }));
163
+ fs.writeSync(
164
+ fd,
165
+ JSON.stringify({ pid: process.pid, time: (/* @__PURE__ */ new Date()).toISOString() })
166
+ );
156
167
  const recovery = _AppendCoordinator.recoverCorruptedTail(filePath);
157
168
  if (recovery.repaired) {
158
169
  repaired = true;
@@ -269,7 +280,23 @@ var AppendCoordinator = class _AppendCoordinator {
269
280
  } catch (err) {
270
281
  const truncateTo = lastLineStart;
271
282
  const discardedBytes = stat.size - truncateTo;
272
- fs.truncateSync(filePath, truncateTo);
283
+ let truncated = false;
284
+ let retries = 5;
285
+ let lastError = null;
286
+ while (retries > 0 && !truncated) {
287
+ try {
288
+ fs.truncateSync(filePath, truncateTo);
289
+ truncated = true;
290
+ } catch (e) {
291
+ lastError = e;
292
+ retries--;
293
+ if (retries > 0) {
294
+ const sharedBuf = new Int32Array(new SharedArrayBuffer(4));
295
+ Atomics.wait(sharedBuf, 0, 0, 10);
296
+ }
297
+ }
298
+ }
299
+ if (!truncated) throw lastError;
273
300
  return {
274
301
  repaired: true,
275
302
  linesDiscarded: discardedBytes,
@@ -311,7 +338,7 @@ var CoreEventBus = class {
311
338
  }
312
339
  }
313
340
  /**
314
- * Normalizes and emits an event.
341
+ * Normalizes and emits an event.
315
342
  * Useful for incremental migration from raw events.
316
343
  */
317
344
  normalizeAndEmit(event) {
@@ -396,7 +423,10 @@ function maskSecrets(data) {
396
423
  let redacted = data.replace(/\b[0-9a-fA-F]{64}\b/g, (match) => {
397
424
  return `${match.slice(0, 6)}...${match.slice(-4)} [REDACTED]`;
398
425
  });
399
- redacted = redacted.replace(/\b([a-z]{3,10}\s+){11,23}[a-z]{3,10}\b/g, "[MNEMONIC REDACTED]");
426
+ redacted = redacted.replace(
427
+ /\b([a-z]{3,10}\s+){11,23}[a-z]{3,10}\b/g,
428
+ "[MNEMONIC REDACTED]"
429
+ );
400
430
  return redacted;
401
431
  }
402
432
  if (Array.isArray(data)) {
@@ -452,7 +482,12 @@ async function writeFileAtomic(targetPath, data, options = {}) {
452
482
  attempts++;
453
483
  if (attempts >= maxAttempts) throw e;
454
484
  if (e.code === "EPERM" || e.code === "EBUSY") {
455
- EnvironmentTelemetry.logAnomaly("FS_RETRY", "low", "fs", `Retrying rename of ${targetPath} due to ${e.code}`);
485
+ EnvironmentTelemetry.logAnomaly(
486
+ "FS_RETRY",
487
+ "low",
488
+ "fs",
489
+ `Retrying rename of ${targetPath} due to ${e.code}`
490
+ );
456
491
  await new Promise((resolve) => setTimeout(resolve, 10 * attempts));
457
492
  continue;
458
493
  }
@@ -470,11 +505,9 @@ async function writeFileAtomic(targetPath, data, options = {}) {
470
505
  }
471
506
  }
472
507
  } catch (err) {
473
- throw new HardkasError(
474
- "IO_ERROR",
475
- `Failed to write file atomically: ${targetPath}`,
476
- { cause: err }
477
- );
508
+ throw new HardkasError("IO_ERROR", `Failed to write file atomically: ${targetPath}`, {
509
+ cause: err
510
+ });
478
511
  } finally {
479
512
  if (fs2.existsSync(tempPath)) {
480
513
  try {
@@ -515,7 +548,12 @@ function writeFileAtomicSync(targetPath, data, options = {}) {
515
548
  attempts++;
516
549
  if (attempts >= maxAttempts) throw e;
517
550
  if (e.code === "EPERM" || e.code === "EBUSY") {
518
- EnvironmentTelemetry.logAnomaly("FS_RETRY", "low", "fs", `Retrying rename sync of ${targetPath} due to ${e.code}`);
551
+ EnvironmentTelemetry.logAnomaly(
552
+ "FS_RETRY",
553
+ "low",
554
+ "fs",
555
+ `Retrying rename sync of ${targetPath} due to ${e.code}`
556
+ );
519
557
  continue;
520
558
  }
521
559
  throw e;
@@ -614,7 +652,9 @@ async function acquireLock(args) {
614
652
  release: async () => {
615
653
  if (fs3.existsSync(lockPath)) {
616
654
  try {
617
- const current = JSON.parse(fs3.readFileSync(lockPath, "utf-8"));
655
+ const current = JSON.parse(
656
+ fs3.readFileSync(lockPath, "utf-8")
657
+ );
618
658
  if (current.pid === process.pid) {
619
659
  fs3.unlinkSync(lockPath);
620
660
  }
@@ -645,13 +685,27 @@ async function acquireLock(args) {
645
685
  staleRecoveryAttempted = true;
646
686
  try {
647
687
  fs3.unlinkSync(lockPath);
648
- EnvironmentTelemetry.logAnomaly("STALE_LOCK_RECOVERY", "medium", "lock", `Recovered corrupted lock file at ${lockPath} (Age: ${ageMs}ms)`, args.rootDir);
688
+ EnvironmentTelemetry.logAnomaly(
689
+ "STALE_LOCK_RECOVERY",
690
+ "medium",
691
+ "lock",
692
+ `Recovered corrupted lock file at ${lockPath} (Age: ${ageMs}ms)`,
693
+ args.rootDir
694
+ );
649
695
  continue;
650
696
  } catch {
651
- throw new HardkasError("LOCK_METADATA_INVALID", `Lock file at ${lockPath} is corrupted and cannot be recovered.`, { cause: err });
697
+ throw new HardkasError(
698
+ "LOCK_METADATA_INVALID",
699
+ `Lock file at ${lockPath} is corrupted and cannot be recovered.`,
700
+ { cause: err }
701
+ );
652
702
  }
653
703
  }
654
- throw new HardkasError("LOCK_METADATA_INVALID", `Lock file at ${lockPath} is corrupted.`, { cause: err });
704
+ throw new HardkasError(
705
+ "LOCK_METADATA_INVALID",
706
+ `Lock file at ${lockPath} is corrupted.`,
707
+ { cause: err }
708
+ );
655
709
  }
656
710
  if (existingMetadata) {
657
711
  const isLocal = existingMetadata.hostname === os.hostname();
@@ -660,7 +714,13 @@ async function acquireLock(args) {
660
714
  staleRecoveryAttempted = true;
661
715
  try {
662
716
  fs3.unlinkSync(lockPath);
663
- EnvironmentTelemetry.logAnomaly("STALE_LOCK_RECOVERY", "medium", "lock", `Recovered lock held by dead process (PID: ${existingMetadata.pid})`, args.rootDir);
717
+ EnvironmentTelemetry.logAnomaly(
718
+ "STALE_LOCK_RECOVERY",
719
+ "medium",
720
+ "lock",
721
+ `Recovered lock held by dead process (PID: ${existingMetadata.pid})`,
722
+ args.rootDir
723
+ );
664
724
  continue;
665
725
  } catch (unlinkErr) {
666
726
  throw new HardkasError(
@@ -678,7 +738,13 @@ async function acquireLock(args) {
678
738
  );
679
739
  }
680
740
  if (args.wait && Date.now() - start < timeoutMs) {
681
- EnvironmentTelemetry.logAnomaly("LOCK_CONTENTION", "low", "lock", `Waiting for lock ${args.name} held by PID ${existingMetadata.pid}`, args.rootDir);
741
+ EnvironmentTelemetry.logAnomaly(
742
+ "LOCK_CONTENTION",
743
+ "low",
744
+ "lock",
745
+ `Waiting for lock ${args.name} held by PID ${existingMetadata.pid}`,
746
+ args.rootDir
747
+ );
682
748
  await new Promise((resolve) => setTimeout(resolve, pollMs));
683
749
  continue;
684
750
  }
@@ -767,10 +833,18 @@ function clearLock(rootDir, name, options = {}) {
767
833
  const isLocal = metadata.hostname === os.hostname();
768
834
  const isAlive = isLocal ? isProcessAlive(metadata.pid) : true;
769
835
  if (options.ifDead) {
770
- if (!isLocal) return { cleared: false, reason: "Cannot verify liveness of remote lock (host: " + metadata.hostname + ")" };
771
- if (isAlive) return { cleared: false, reason: `Process (PID: ${metadata.pid}) is still alive` };
836
+ if (!isLocal)
837
+ return {
838
+ cleared: false,
839
+ reason: "Cannot verify liveness of remote lock (host: " + metadata.hostname + ")"
840
+ };
841
+ if (isAlive)
842
+ return { cleared: false, reason: `Process (PID: ${metadata.pid}) is still alive` };
772
843
  } else if (!options.force) {
773
- return { cleared: false, reason: "Lock is potentially active. Use --force or --if-dead." };
844
+ return {
845
+ cleared: false,
846
+ reason: "Lock is potentially active. Use --force or --if-dead."
847
+ };
774
848
  }
775
849
  fs3.unlinkSync(lockPath);
776
850
  return { cleared: true };
@@ -823,7 +897,10 @@ function diffReplays(replayA, replayB) {
823
897
  const timeA = new Date(tsA).getTime();
824
898
  const timeB = new Date(tsB).getTime();
825
899
  if (timeA !== timeB) {
826
- diff.observational.timestampShifts.push({ path: "timestamp", shiftMs: Math.abs(timeA - timeB) });
900
+ diff.observational.timestampShifts.push({
901
+ path: "timestamp",
902
+ shiftMs: Math.abs(timeA - timeB)
903
+ });
827
904
  }
828
905
  }
829
906
  return diff;
@@ -879,7 +956,7 @@ async function createSnapshot(options) {
879
956
  const manifest = {
880
957
  snapshotVersion: 1,
881
958
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
882
- hardkasVersion: "0.7.3-alpha",
959
+ hardkasVersion: "0.7.5-alpha",
883
960
  stateAuthority: "filesystem",
884
961
  projectionAuthority: "sqlite",
885
962
  deterministicScope,
@@ -924,7 +1001,10 @@ var TelemetryRotator = class {
924
1001
  }
925
1002
  const stats = fs5.statSync(activeFile);
926
1003
  if (stats.size < maxSizeBytes) {
927
- return { rotated: false, reason: `File size (${stats.size}) is below threshold (${maxSizeBytes})` };
1004
+ return {
1005
+ rotated: false,
1006
+ reason: `File size (${stats.size}) is below threshold (${maxSizeBytes})`
1007
+ };
928
1008
  }
929
1009
  return this.forceRotate(rootDir);
930
1010
  }
@@ -1019,7 +1099,9 @@ function verifyArtifactIntegrity(identity, computedHash) {
1019
1099
  }
1020
1100
  function verifyReplay(identity, replayCtx) {
1021
1101
  if (identity.semanticHash !== replayCtx.semanticHash) {
1022
- throw new Error(`[CRITICAL SEMANTIC ERROR] Replay semantic hash divergence: expected ${identity.semanticHash}, got ${replayCtx.semanticHash}`);
1102
+ throw new Error(
1103
+ `[CRITICAL SEMANTIC ERROR] Replay semantic hash divergence: expected ${identity.semanticHash}, got ${replayCtx.semanticHash}`
1104
+ );
1023
1105
  }
1024
1106
  validateStatusTransition(identity.status, "REPLAY_VERIFIED");
1025
1107
  return "REPLAY_VERIFIED";
@@ -1042,10 +1124,14 @@ function verifyCapabilityBoundary(identity, capability) {
1042
1124
  // src/semantics/migration.ts
1043
1125
  function verifyMigrationIntegrity(preMigration, postMigration) {
1044
1126
  if (preMigration.artifactId !== postMigration.artifactId) {
1045
- throw new Error(`[CRITICAL SEMANTIC ERROR] Migration unexpectedly altered canonical artifact ID: ${preMigration.artifactId} -> ${postMigration.artifactId}`);
1127
+ throw new Error(
1128
+ `[CRITICAL SEMANTIC ERROR] Migration unexpectedly altered canonical artifact ID: ${preMigration.artifactId} -> ${postMigration.artifactId}`
1129
+ );
1046
1130
  }
1047
1131
  if (postMigration.schemaVersion < preMigration.schemaVersion) {
1048
- throw new Error(`[CRITICAL SEMANTIC ERROR] Invalid migration: schema downgraded from ${preMigration.schemaVersion} to ${postMigration.schemaVersion}`);
1132
+ throw new Error(
1133
+ `[CRITICAL SEMANTIC ERROR] Invalid migration: schema downgraded from ${preMigration.schemaVersion} to ${postMigration.schemaVersion}`
1134
+ );
1049
1135
  }
1050
1136
  }
1051
1137
  function migrateArtifact(identity, targetVersion) {
@@ -1060,7 +1146,9 @@ function migrateArtifact(identity, targetVersion) {
1060
1146
  }
1061
1147
  function comparePrePostMigrationLineage(preLineageId, postLineageId) {
1062
1148
  if (preLineageId !== postLineageId) {
1063
- throw new Error(`[CRITICAL SEMANTIC ERROR] Lineage broken across schema migration: ${preLineageId} -> ${postLineageId}`);
1149
+ throw new Error(
1150
+ `[CRITICAL SEMANTIC ERROR] Lineage broken across schema migration: ${preLineageId} -> ${postLineageId}`
1151
+ );
1064
1152
  }
1065
1153
  }
1066
1154
 
@@ -1098,7 +1186,12 @@ function detectSemanticDrift(dashboardView, queryStoreView, replayView, filesyst
1098
1186
  return { hasDrift: false, severity: "NONE" };
1099
1187
  }
1100
1188
  function assertNoSemanticDrift(dashboardView, queryStoreView, replayView, filesystemView) {
1101
- const report = detectSemanticDrift(dashboardView, queryStoreView, replayView, filesystemView);
1189
+ const report = detectSemanticDrift(
1190
+ dashboardView,
1191
+ queryStoreView,
1192
+ replayView,
1193
+ filesystemView
1194
+ );
1102
1195
  if (report.hasDrift) {
1103
1196
  throw new Error(
1104
1197
  `[CRITICAL SEMANTIC DRIFT] Subsystem disagreement detected.
@@ -1112,14 +1205,18 @@ Resolution Command: ${report.exactReplayCommand}`
1112
1205
  // src/migrations.ts
1113
1206
  import fs6 from "fs";
1114
1207
  import path8 from "path";
1115
- var CURRENT_RUNTIME_VERSION = "0.7.3-alpha";
1208
+ var CURRENT_RUNTIME_VERSION = "0.7.5-alpha";
1116
1209
  var MIN_SUPPORTED_VERSION = "0.5.0-alpha";
1117
1210
  var MigrationManager = class {
1118
1211
  static checkVersion(rootDir) {
1119
1212
  const versionFile = path8.join(rootDir, ".hardkas", "version.json");
1120
1213
  if (!fs6.existsSync(versionFile)) {
1121
1214
  this.writeVersion(rootDir, CURRENT_RUNTIME_VERSION);
1122
- return { needsMigration: false, canDowngrade: true, currentVersion: CURRENT_RUNTIME_VERSION };
1215
+ return {
1216
+ needsMigration: false,
1217
+ canDowngrade: true,
1218
+ currentVersion: CURRENT_RUNTIME_VERSION
1219
+ };
1123
1220
  }
1124
1221
  try {
1125
1222
  const data = JSON.parse(fs6.readFileSync(versionFile, "utf-8"));
@@ -1131,30 +1228,49 @@ var MigrationManager = class {
1131
1228
  return { needsMigration: false, canDowngrade: false, currentVersion: wsVersion };
1132
1229
  }
1133
1230
  if (this.compareSemver(wsVersion, MIN_SUPPORTED_VERSION) < 0) {
1134
- throw new HardkasError("MIGRATION_UNSUPPORTED", `Workspace version ${wsVersion} is too old to migrate to ${CURRENT_RUNTIME_VERSION}`);
1231
+ throw new HardkasError(
1232
+ "MIGRATION_UNSUPPORTED",
1233
+ `Workspace version ${wsVersion} is too old to migrate to ${CURRENT_RUNTIME_VERSION}`
1234
+ );
1135
1235
  }
1136
1236
  return { needsMigration: true, canDowngrade: true, currentVersion: wsVersion };
1137
1237
  } catch (err) {
1138
1238
  if (err instanceof HardkasError) throw err;
1139
- throw new HardkasError("MIGRATION_ERROR", `Failed to parse version.json: ${err.message}`);
1239
+ throw new HardkasError(
1240
+ "MIGRATION_ERROR",
1241
+ `Failed to parse version.json: ${err.message}`
1242
+ );
1140
1243
  }
1141
1244
  }
1142
1245
  static migrate(rootDir, dryRun = false) {
1143
1246
  const status = this.checkVersion(rootDir);
1144
1247
  if (!status.canDowngrade) {
1145
- throw new HardkasError("DOWNGRADE_REFUSED", `Cannot safely downgrade from workspace version ${status.currentVersion} to runtime version ${CURRENT_RUNTIME_VERSION}.`);
1248
+ throw new HardkasError(
1249
+ "DOWNGRADE_REFUSED",
1250
+ `Cannot safely downgrade from workspace version ${status.currentVersion} to runtime version ${CURRENT_RUNTIME_VERSION}.`
1251
+ );
1146
1252
  }
1147
1253
  if (!status.needsMigration) return;
1148
1254
  if (dryRun) {
1149
- console.log(`[DRY-RUN] Would migrate workspace from ${status.currentVersion} to ${CURRENT_RUNTIME_VERSION}`);
1255
+ console.log(
1256
+ `[DRY-RUN] Would migrate workspace from ${status.currentVersion} to ${CURRENT_RUNTIME_VERSION}`
1257
+ );
1150
1258
  return;
1151
1259
  }
1152
1260
  this.backupWorkspace(rootDir);
1153
1261
  try {
1154
1262
  this.writeVersion(rootDir, CURRENT_RUNTIME_VERSION);
1155
1263
  } catch (err) {
1156
- getTelemetry().logAnomaly("EXTERNAL_MUTATION", "critical", "projection", `Migration failed: ${err.message}`);
1157
- throw new HardkasError("MIGRATION_FAILED", `Migration failed, workspace might be corrupted: ${err.message}`);
1264
+ getTelemetry().logAnomaly(
1265
+ "EXTERNAL_MUTATION",
1266
+ "critical",
1267
+ "projection",
1268
+ `Migration failed: ${err.message}`
1269
+ );
1270
+ throw new HardkasError(
1271
+ "MIGRATION_FAILED",
1272
+ `Migration failed, workspace might be corrupted: ${err.message}`
1273
+ );
1158
1274
  }
1159
1275
  }
1160
1276
  static writeVersion(rootDir, version) {
@@ -1195,11 +1311,7 @@ var kaspaNetworkIdSchema = z.enum([
1195
1311
  "devnet",
1196
1312
  "simulated"
1197
1313
  ]);
1198
- var executionModeSchema = z.enum([
1199
- "simulated",
1200
- "real",
1201
- "readonly"
1202
- ]);
1314
+ var executionModeSchema = z.enum(["simulated", "real", "readonly"]);
1203
1315
  var artifactTypeSchema = z.enum([
1204
1316
  "txPlan",
1205
1317
  "signedTx",
@@ -1239,7 +1351,9 @@ var InvariantViolationError = class extends HardkasError {
1239
1351
  domain;
1240
1352
  severity;
1241
1353
  constructor(domain, message, options) {
1242
- super(`INVARIANT_VIOLATION_${domain.toUpperCase()}`, message, { cause: options?.cause });
1354
+ super(`INVARIANT_VIOLATION_${domain.toUpperCase()}`, message, {
1355
+ cause: options?.cause
1356
+ });
1243
1357
  this.name = "InvariantViolationError";
1244
1358
  this.domain = domain;
1245
1359
  this.severity = options?.severity || "fatal";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hardkas/core",
3
- "version": "0.7.3-alpha",
3
+ "version": "0.7.5-alpha",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",