@forgezero/agent 0.1.92 → 0.1.95

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.
@@ -917,7 +917,7 @@ async function postSignedNode(options, path, body) {
917
917
  }
918
918
 
919
919
  // src/version.ts
920
- var VERSION3 = "0.1.92";
920
+ var VERSION3 = "0.1.95";
921
921
 
922
922
  // src/agent-heartbeat.ts
923
923
  function readAgentHostMetrics() {
@@ -192,6 +192,13 @@ export declare function validateBootstrapConfig(value: BootstrapConfig): Bootstr
192
192
  export declare function planBootstrap(input: BootstrapConfig, initialized?: boolean): BootstrapPlan;
193
193
  export declare function bootstrapIdentityDigest(config: BootstrapConfig): string;
194
194
  export declare const legacyBootstrapIdentityDigest: (config: BootstrapConfig) => string;
195
+ /**
196
+ * Exact, reviewed identity migrations for an already-installed platform host.
197
+ * This is deliberately not a generic "stored coordinates match" escape hatch:
198
+ * only the development collector transition from the retired external OTLP
199
+ * placeholder to the supervised loopback sink is accepted.
200
+ */
201
+ export declare function approvedPlatformRepairIdentityDigests(config: PlatformBootstrapConfig): readonly string[];
195
202
  /** Exact prior-release identities accepted only while generation one is still unenrolled. */
196
203
  export declare function interruptedPlatformReleaseIdentityDigests(config: PlatformBootstrapConfig, releaseEvidence: {
197
204
  revision: string;
package/dist/bootstrap.js CHANGED
@@ -1420,7 +1420,7 @@ var UPDATE_RETRY_BASE_MS = 5 * 60000;
1420
1420
  var UPDATE_RETRY_MAX_MS = 24 * 60 * 60000;
1421
1421
 
1422
1422
  // src/version.ts
1423
- var VERSION = "0.1.92";
1423
+ var VERSION = "0.1.95";
1424
1424
 
1425
1425
  // src/software.ts
1426
1426
  var PINNED_BUN_VERSION = "1.3.14";
@@ -3642,7 +3642,8 @@ async function ensureForgeZeroOtelCollector(host, exportEndpoint) {
3642
3642
  host.write(CONFIG, rendered.config, 420);
3643
3643
  host.write(UNIT, rendered.unit, 420);
3644
3644
  await checked2(host, ["/usr/bin/systemctl", "daemon-reload"]);
3645
- await checked2(host, ["/usr/bin/systemctl", "enable", "--now", FORGEZERO_OTEL_COLLECTOR_UNIT]);
3645
+ await checked2(host, ["/usr/bin/systemctl", "enable", FORGEZERO_OTEL_COLLECTOR_UNIT]);
3646
+ await checked2(host, ["/usr/bin/systemctl", "restart", FORGEZERO_OTEL_COLLECTOR_UNIT]);
3646
3647
  let ready = false;
3647
3648
  for (let attempt = 0;attempt < 100; attempt += 1) {
3648
3649
  const probe = await host.exec([
@@ -4289,6 +4290,14 @@ function bootstrapIdentityDigest(config) {
4289
4290
  return createHash2("sha256").update(JSON.stringify(bootstrapIdentity(config))).digest("hex");
4290
4291
  }
4291
4292
  var legacyBootstrapIdentityDigest = (config) => createHash2("sha256").update(JSON.stringify(bootstrapIdentity(config, true))).digest("hex");
4293
+ function approvedPlatformRepairIdentityDigests(config) {
4294
+ if (config.environment !== "development" || config.telemetryEndpoint !== LOCAL_DEBUG_OTEL_EXPORT || config.runtime.environment.agentOtlpEndpoint !== "http://127.0.0.1:4318")
4295
+ return [];
4296
+ const previous = structuredClone(config);
4297
+ previous.telemetryEndpoint = "https://otel.forgezero.net";
4298
+ previous.runtime.environment.agentOtlpEndpoint = "https://otel.forgezero.net";
4299
+ return [bootstrapIdentityDigest(previous), legacyBootstrapIdentityDigest(previous)];
4300
+ }
4292
4301
  function interruptedPlatformReleaseIdentityDigests(config, releaseEvidence, bootstrapManifest) {
4293
4302
  if (!config.runtime.environment.initialInventory)
4294
4303
  return [];
@@ -4609,10 +4618,11 @@ async function applyBootstrap(input, host = localBootstrapHost(), secrets, depen
4609
4618
  if (installed) {
4610
4619
  const exactIdentity = installed.kind === config.kind && installed.identityDigest === bootstrapIdentityDigest(config);
4611
4620
  const boundedReleaseResume = config.kind === "platform" && !host.exists("/var/lib/forgezero/enrolment.json") && host.exists(BOOTSTRAP_RELEASE_EVIDENCE) && storedPlatformCoordinatesMatch(installed, config);
4612
- if (!exactIdentity && !boundedReleaseResume) {
4621
+ const approvedIdentityMigration = config.kind === "platform" && storedPlatformCoordinatesMatch(installed, config) && approvedPlatformRepairIdentityDigests(config).includes(installed.identityDigest);
4622
+ if (!exactIdentity && !boundedReleaseResume && !approvedIdentityMigration) {
4613
4623
  throw new Error("bootstrap repair coordinates do not match the installed host identity");
4614
4624
  }
4615
- allowInterruptedReleaseRebind = !exactIdentity && boundedReleaseResume;
4625
+ allowInterruptedReleaseRebind = !exactIdentity && (boundedReleaseResume || approvedIdentityMigration);
4616
4626
  }
4617
4627
  const platformPrivate = config.kind === "platform" ? (() => {
4618
4628
  if (!secrets)
@@ -5218,6 +5228,7 @@ export {
5218
5228
  interruptedPlatformReleaseIdentityDigests,
5219
5229
  bootstrapStatus,
5220
5230
  bootstrapIdentityDigest,
5231
+ approvedPlatformRepairIdentityDigests,
5221
5232
  applyBootstrap,
5222
5233
  PLATFORM_BOOTSTRAP_PROFILES,
5223
5234
  BOOTSTRAP_STATE_PATH
package/dist/fz-agent.js CHANGED
@@ -9496,7 +9496,7 @@ async function writeAndCloseProcessInput(input, value) {
9496
9496
  }
9497
9497
 
9498
9498
  // src/version.ts
9499
- var VERSION2 = "0.1.92";
9499
+ var VERSION2 = "0.1.95";
9500
9500
 
9501
9501
  // src/ssh-bootstrap.ts
9502
9502
  class SshBootstrapError extends Error {
package/dist/fz.js CHANGED
@@ -4810,7 +4810,8 @@ async function spawnWith(command, env, report = () => {}, options = {}) {
4810
4810
  }
4811
4811
 
4812
4812
  // src/cli/index.ts
4813
- import { existsSync as existsSync13, lstatSync as lstatSync10, mkdirSync as mkdirSync13, readFileSync as readFileSync16, writeFileSync as writeFileSync13 } from "fs";
4813
+ import { existsSync as existsSync13, lstatSync as lstatSync10, mkdirSync as mkdirSync13, readFileSync as readFileSync16, renameSync as renameSync10, rmSync as rmSync8, writeFileSync as writeFileSync13 } from "fs";
4814
+ import { randomBytes as randomBytes10 } from "crypto";
4814
4815
  import { basename as basename3, dirname as dirname14, isAbsolute as isAbsolute7, join as join13, resolve as resolve12 } from "path";
4815
4816
 
4816
4817
  // src/process-input.ts
@@ -4840,7 +4841,7 @@ var UPDATE_RETRY_BASE_MS = 5 * 60000;
4840
4841
  var UPDATE_RETRY_MAX_MS = 24 * 60 * 60000;
4841
4842
 
4842
4843
  // src/version.ts
4843
- var VERSION2 = "0.1.92";
4844
+ var VERSION2 = "0.1.95";
4844
4845
 
4845
4846
  // src/software.ts
4846
4847
  var PINNED_BUN_VERSION = "1.3.14";
@@ -13868,7 +13869,8 @@ async function ensureForgeZeroOtelCollector(host, exportEndpoint) {
13868
13869
  host.write(CONFIG, rendered.config, 420);
13869
13870
  host.write(UNIT, rendered.unit, 420);
13870
13871
  await checked(host, ["/usr/bin/systemctl", "daemon-reload"]);
13871
- await checked(host, ["/usr/bin/systemctl", "enable", "--now", FORGEZERO_OTEL_COLLECTOR_UNIT]);
13872
+ await checked(host, ["/usr/bin/systemctl", "enable", FORGEZERO_OTEL_COLLECTOR_UNIT]);
13873
+ await checked(host, ["/usr/bin/systemctl", "restart", FORGEZERO_OTEL_COLLECTOR_UNIT]);
13872
13874
  let ready = false;
13873
13875
  for (let attempt = 0;attempt < 100; attempt += 1) {
13874
13876
  const probe = await host.exec([
@@ -14673,6 +14675,14 @@ function bootstrapIdentityDigest(config) {
14673
14675
  return createHash4("sha256").update(JSON.stringify(bootstrapIdentity(config))).digest("hex");
14674
14676
  }
14675
14677
  var legacyBootstrapIdentityDigest = (config) => createHash4("sha256").update(JSON.stringify(bootstrapIdentity(config, true))).digest("hex");
14678
+ function approvedPlatformRepairIdentityDigests(config) {
14679
+ if (config.environment !== "development" || config.telemetryEndpoint !== LOCAL_DEBUG_OTEL_EXPORT || config.runtime.environment.agentOtlpEndpoint !== "http://127.0.0.1:4318")
14680
+ return [];
14681
+ const previous = structuredClone(config);
14682
+ previous.telemetryEndpoint = "https://otel.forgezero.net";
14683
+ previous.runtime.environment.agentOtlpEndpoint = "https://otel.forgezero.net";
14684
+ return [bootstrapIdentityDigest(previous), legacyBootstrapIdentityDigest(previous)];
14685
+ }
14676
14686
  function interruptedPlatformReleaseIdentityDigests(config, releaseEvidence, bootstrapManifest) {
14677
14687
  if (!config.runtime.environment.initialInventory)
14678
14688
  return [];
@@ -14993,10 +15003,11 @@ async function applyBootstrap(input, host = localBootstrapHost(), secrets, depen
14993
15003
  if (installed) {
14994
15004
  const exactIdentity = installed.kind === config.kind && installed.identityDigest === bootstrapIdentityDigest(config);
14995
15005
  const boundedReleaseResume = config.kind === "platform" && !host.exists("/var/lib/forgezero/enrolment.json") && host.exists(BOOTSTRAP_RELEASE_EVIDENCE) && storedPlatformCoordinatesMatch(installed, config);
14996
- if (!exactIdentity && !boundedReleaseResume) {
15006
+ const approvedIdentityMigration = config.kind === "platform" && storedPlatformCoordinatesMatch(installed, config) && approvedPlatformRepairIdentityDigests(config).includes(installed.identityDigest);
15007
+ if (!exactIdentity && !boundedReleaseResume && !approvedIdentityMigration) {
14997
15008
  throw new Error("bootstrap repair coordinates do not match the installed host identity");
14998
15009
  }
14999
- allowInterruptedReleaseRebind = !exactIdentity && boundedReleaseResume;
15010
+ allowInterruptedReleaseRebind = !exactIdentity && (boundedReleaseResume || approvedIdentityMigration);
15000
15011
  }
15001
15012
  const platformPrivate = config.kind === "platform" ? (() => {
15002
15013
  if (!secrets)
@@ -19440,6 +19451,17 @@ function writeMetalOperatorFiles(directory) {
19440
19451
  });
19441
19452
  return { metalConfig, remoteRequest };
19442
19453
  }
19454
+ function writeDerivedLaunchFile(path, write) {
19455
+ const temporary = `${path}.next.${process.pid}.${randomBytes10(6).toString("hex")}`;
19456
+ try {
19457
+ write(temporary);
19458
+ renameSync10(temporary, path);
19459
+ return path;
19460
+ } catch (cause) {
19461
+ rmSync8(temporary, { force: true });
19462
+ throw cause;
19463
+ }
19464
+ }
19443
19465
  function writePlatformGenesisFleet(directory, preset) {
19444
19466
  const output = genesisOutputDirectory(directory);
19445
19467
  const metalRequestFile = preset?.metalRequestFile ?? bootstrapAnswer("Owner-only metal remote request containing the reviewed genesis guests");
@@ -19462,7 +19484,8 @@ function writePlatformGenesisFleet(directory, preset) {
19462
19484
  cloudflareHandoffFile: cloudflareHostHandoffPath(checkpointPath, guest.name)
19463
19485
  }));
19464
19486
  const realtimeEnabled = preset ? true : bootstrapBoolean("Configure existing Worker realtime fan-out?", "yes");
19465
- const cloudflareConfig = writeBootstrapConfig(join13(output, "cloudflare.json"), createCloudflareBootstrapDiscoveryCommandConfig({
19487
+ const cloudflareConfigPath = join13(output, "cloudflare.json");
19488
+ const cloudflareConfigValue = createCloudflareBootstrapDiscoveryCommandConfig({
19466
19489
  checkpointPath,
19467
19490
  discovery: {
19468
19491
  zoneName: preset?.profile.zoneName ?? bootstrapAnswer("Cloudflare DNS zone name", "forgezero.net"),
@@ -19479,7 +19502,8 @@ function writePlatformGenesisFleet(directory, preset) {
19479
19502
  service: "http://127.0.0.1:3000",
19480
19503
  tunnelName: preset ? guest.name : bootstrapAnswer(`${guest.name} Tunnel name`, guest.name)
19481
19504
  }))
19482
- }));
19505
+ });
19506
+ const cloudflareConfig = preset ? writeDerivedLaunchFile(cloudflareConfigPath, (path) => writeBootstrapConfig(path, cloudflareConfigValue)) : writeBootstrapConfig(cloudflareConfigPath, cloudflareConfigValue);
19483
19507
  const cloudflareAcceptance = join13(output, "cloudflare-acceptance.json");
19484
19508
  const configs = platformGenesisBootstrapConfigs(template, fleet, nodes, metalHostname, region, preset ? {
19485
19509
  source: "bootstrap-bundle",
@@ -19488,13 +19512,17 @@ function writePlatformGenesisFleet(directory, preset) {
19488
19512
  bundleSha256: preset.bundle.manifest.sha256
19489
19513
  } : undefined).map((config) => {
19490
19514
  const path = `${output}/${config.computeReference}-platform.json`;
19491
- writeBootstrapConfig(path, config);
19515
+ if (preset)
19516
+ writeDerivedLaunchFile(path, (temporary) => writeBootstrapConfig(temporary, config));
19517
+ else
19518
+ writeBootstrapConfig(path, config);
19492
19519
  return path;
19493
19520
  });
19494
19521
  const requests = configs.map((platformConfigFile, index) => {
19495
19522
  const guest = fleet[index];
19496
19523
  const host = guestHostKeys.nodes.find(({ name }) => name === guest.name);
19497
- return writeOperatorPlatformBootstrapRequest(join13(output, `${guest.name}-remote.json`), {
19524
+ const path = join13(output, `${guest.name}-remote.json`);
19525
+ const request = {
19498
19526
  kind: "platform-remote",
19499
19527
  platformConfigFile,
19500
19528
  target: {
@@ -19513,9 +19541,12 @@ function writePlatformGenesisFleet(directory, preset) {
19513
19541
  hostKeySha256: metalRequest.target.hostKeySha256
19514
19542
  }
19515
19543
  }
19516
- });
19544
+ };
19545
+ return preset ? writeDerivedLaunchFile(path, (temporary) => writeOperatorPlatformBootstrapRequest(temporary, request)) : writeOperatorPlatformBootstrapRequest(path, request);
19517
19546
  });
19518
- const fleetRequest = writeOperatorPlatformBootstrapFleetRequest(join13(output, "platform-fleet-remote.json"), requests, { configFile: cloudflareConfig, acceptanceFile: cloudflareAcceptance });
19547
+ const fleetPath = join13(output, "platform-fleet-remote.json");
19548
+ const writeFleet = (path) => writeOperatorPlatformBootstrapFleetRequest(path, requests, { configFile: cloudflareConfig, acceptanceFile: cloudflareAcceptance });
19549
+ const fleetRequest = preset ? writeDerivedLaunchFile(fleetPath, writeFleet) : writeFleet(fleetPath);
19519
19550
  return { configs, requests, fleetRequest, cloudflareConfig, cloudflareAcceptance };
19520
19551
  }
19521
19552
  function selectedForgeZeroLaunchEnvironment(value) {
@@ -19777,8 +19808,7 @@ async function cmdBootstrap(options, args) {
19777
19808
  }
19778
19809
  const outputDirectory = options.outputPath ?? join13(homedir2(), ".forgezero-secure", environment, "genesis");
19779
19810
  const environmentInput = options.bootstrapSecretsEnvFile ? readPlatformLaunchEnvironment(options.bootstrapSecretsEnvFile) : undefined;
19780
- const existingFleetPath = join13(outputDirectory, "platform-fleet-remote.json");
19781
- const fleet = existsSync13(existingFleetPath) ? readOperatorPlatformBootstrapFleetRequest(existingFleetPath) : readOperatorPlatformBootstrapFleetRequest((await prepareForgeZeroPlatformLaunch(environment, outputDirectory, options.projectRoot, environmentInput?.owner)).fleetRequest);
19811
+ const fleet = readOperatorPlatformBootstrapFleetRequest((await prepareForgeZeroPlatformLaunch(environment, outputDirectory, options.projectRoot, environmentInput?.owner)).fleetRequest);
19782
19812
  if (planOperatorPlatformFleetBootstrap(fleet, "apply").environment !== environment) {
19783
19813
  throw new Error("existing platform fleet does not match the selected launch profile");
19784
19814
  }
@@ -366,7 +366,7 @@ function systemdAgentEgressDirectives(loopbackTcpPorts = []) {
366
366
  }
367
367
 
368
368
  // src/version.ts
369
- var VERSION = "0.1.92";
369
+ var VERSION = "0.1.95";
370
370
 
371
371
  // src/otel-collector.ts
372
372
  var FORGEZERO_OTEL_COLLECTOR_UNIT = "forgezero-otel-collector.service";
@@ -499,7 +499,8 @@ async function ensureForgeZeroOtelCollector(host, exportEndpoint) {
499
499
  host.write(CONFIG, rendered.config, 420);
500
500
  host.write(UNIT, rendered.unit, 420);
501
501
  await checked2(host, ["/usr/bin/systemctl", "daemon-reload"]);
502
- await checked2(host, ["/usr/bin/systemctl", "enable", "--now", FORGEZERO_OTEL_COLLECTOR_UNIT]);
502
+ await checked2(host, ["/usr/bin/systemctl", "enable", FORGEZERO_OTEL_COLLECTOR_UNIT]);
503
+ await checked2(host, ["/usr/bin/systemctl", "restart", FORGEZERO_OTEL_COLLECTOR_UNIT]);
503
504
  let ready = false;
504
505
  for (let attempt = 0;attempt < 100; attempt += 1) {
505
506
  const probe = await host.exec([
@@ -1420,7 +1420,7 @@ var UPDATE_RETRY_BASE_MS = 5 * 60000;
1420
1420
  var UPDATE_RETRY_MAX_MS = 24 * 60 * 60000;
1421
1421
 
1422
1422
  // src/version.ts
1423
- var VERSION = "0.1.92";
1423
+ var VERSION = "0.1.95";
1424
1424
 
1425
1425
  // src/software.ts
1426
1426
  var PINNED_BUN_VERSION = "1.3.14";
@@ -3642,7 +3642,8 @@ async function ensureForgeZeroOtelCollector(host, exportEndpoint) {
3642
3642
  host.write(CONFIG, rendered.config, 420);
3643
3643
  host.write(UNIT, rendered.unit, 420);
3644
3644
  await checked2(host, ["/usr/bin/systemctl", "daemon-reload"]);
3645
- await checked2(host, ["/usr/bin/systemctl", "enable", "--now", FORGEZERO_OTEL_COLLECTOR_UNIT]);
3645
+ await checked2(host, ["/usr/bin/systemctl", "enable", FORGEZERO_OTEL_COLLECTOR_UNIT]);
3646
+ await checked2(host, ["/usr/bin/systemctl", "restart", FORGEZERO_OTEL_COLLECTOR_UNIT]);
3646
3647
  let ready = false;
3647
3648
  for (let attempt = 0;attempt < 100; attempt += 1) {
3648
3649
  const probe = await host.exec([
@@ -4289,6 +4290,14 @@ function bootstrapIdentityDigest(config) {
4289
4290
  return createHash2("sha256").update(JSON.stringify(bootstrapIdentity(config))).digest("hex");
4290
4291
  }
4291
4292
  var legacyBootstrapIdentityDigest = (config) => createHash2("sha256").update(JSON.stringify(bootstrapIdentity(config, true))).digest("hex");
4293
+ function approvedPlatformRepairIdentityDigests(config) {
4294
+ if (config.environment !== "development" || config.telemetryEndpoint !== LOCAL_DEBUG_OTEL_EXPORT || config.runtime.environment.agentOtlpEndpoint !== "http://127.0.0.1:4318")
4295
+ return [];
4296
+ const previous = structuredClone(config);
4297
+ previous.telemetryEndpoint = "https://otel.forgezero.net";
4298
+ previous.runtime.environment.agentOtlpEndpoint = "https://otel.forgezero.net";
4299
+ return [bootstrapIdentityDigest(previous), legacyBootstrapIdentityDigest(previous)];
4300
+ }
4292
4301
  function interruptedPlatformReleaseIdentityDigests(config, releaseEvidence, bootstrapManifest) {
4293
4302
  if (!config.runtime.environment.initialInventory)
4294
4303
  return [];
@@ -4609,10 +4618,11 @@ async function applyBootstrap(input, host = localBootstrapHost(), secrets, depen
4609
4618
  if (installed) {
4610
4619
  const exactIdentity = installed.kind === config.kind && installed.identityDigest === bootstrapIdentityDigest(config);
4611
4620
  const boundedReleaseResume = config.kind === "platform" && !host.exists("/var/lib/forgezero/enrolment.json") && host.exists(BOOTSTRAP_RELEASE_EVIDENCE) && storedPlatformCoordinatesMatch(installed, config);
4612
- if (!exactIdentity && !boundedReleaseResume) {
4621
+ const approvedIdentityMigration = config.kind === "platform" && storedPlatformCoordinatesMatch(installed, config) && approvedPlatformRepairIdentityDigests(config).includes(installed.identityDigest);
4622
+ if (!exactIdentity && !boundedReleaseResume && !approvedIdentityMigration) {
4613
4623
  throw new Error("bootstrap repair coordinates do not match the installed host identity");
4614
4624
  }
4615
- allowInterruptedReleaseRebind = !exactIdentity && boundedReleaseResume;
4625
+ allowInterruptedReleaseRebind = !exactIdentity && (boundedReleaseResume || approvedIdentityMigration);
4616
4626
  }
4617
4627
  const platformPrivate = config.kind === "platform" ? (() => {
4618
4628
  if (!secrets)
@@ -2908,7 +2908,7 @@ function requestSoftware(requirements, socketPath = DEFAULT_SOFTWARE_HELPER_SOCK
2908
2908
  }
2909
2909
 
2910
2910
  // src/version.ts
2911
- var VERSION3 = "0.1.92";
2911
+ var VERSION3 = "0.1.95";
2912
2912
 
2913
2913
  // src/egress-policy.ts
2914
2914
  import { realpathSync as realpathSync3 } from "node:fs";
package/dist/provision.js CHANGED
@@ -2908,7 +2908,7 @@ function requestSoftware(requirements, socketPath = DEFAULT_SOFTWARE_HELPER_SOCK
2908
2908
  }
2909
2909
 
2910
2910
  // src/version.ts
2911
- var VERSION3 = "0.1.92";
2911
+ var VERSION3 = "0.1.95";
2912
2912
 
2913
2913
  // src/egress-policy.ts
2914
2914
  import { realpathSync as realpathSync3 } from "node:fs";
package/dist/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  /** One package version shared by both public binaries. Pinned to package.json by tests. */
2
- export declare const VERSION = "0.1.92";
2
+ export declare const VERSION = "0.1.95";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forgezero/agent",
3
- "version": "0.1.92",
3
+ "version": "0.1.95",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "check": "tsc --noEmit",