@forgezero/agent 0.1.62 → 0.1.63

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.
@@ -60,8 +60,6 @@ export interface PlatformSharedEnvironment {
60
60
  endpoint: string;
61
61
  producer: string;
62
62
  };
63
- repository: string;
64
- branch: string;
65
63
  deployProfile: string;
66
64
  }
67
65
  export declare function validatePlatformSharedEnvironment(input: PlatformSharedEnvironment): PlatformSharedEnvironment;
@@ -100,8 +100,6 @@ function validatePlatformSharedEnvironment(input) {
100
100
  databaseUser: input.databaseUser,
101
101
  sharedDirectory: input.sharedDirectory,
102
102
  seedSyncEpoch: input.seedSyncEpoch,
103
- repository: input.repository,
104
- branch: input.branch,
105
103
  deployProfile: input.deployProfile
106
104
  }))
107
105
  safeAtom(name, value);
@@ -184,8 +182,6 @@ function renderPlatformSharedEnvironment(input) {
184
182
  FZ_AGENT_OTLP_ENDPOINT: value.agentOtlpEndpoint,
185
183
  FZ_CUSTODIAN_EMAIL: value.custodianEmail ?? "",
186
184
  FZ_PROFILE: value.deployProfile,
187
- FZ_REPO: value.repository,
188
- FZ_BRANCH: value.branch,
189
185
  FZ_EMAIL_PROVIDER: value.email?.provider ?? "",
190
186
  FZ_SMTP_HOST: value.email?.provider === "smtp" ? value.email.host : "",
191
187
  FZ_SMTP_PORT: value.email?.provider === "smtp" ? String(value.email.port) : "",
@@ -709,7 +709,8 @@ var SOFTWARE_CATALOG = [
709
709
  { id: "cloudflared", version: "2026.7.3", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
710
710
  { id: "cloudflare-warp", version: "2026.6.822.0-min", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
711
711
  { id: "ufw", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
712
- { id: "openssh-client", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" }
712
+ { id: "openssh-client", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
713
+ { id: "git", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" }
713
714
  ];
714
715
  var UBUNTU_2604_X64 = [
715
716
  { requirement: { id: "bun", version: "1.3.14" } },
@@ -719,7 +720,8 @@ var UBUNTU_2604_X64 = [
719
720
  { requirement: { id: "cloudflared", version: "2026.7.3" } },
720
721
  { requirement: { id: "cloudflare-warp", version: "2026.6.822.0-min" } },
721
722
  { requirement: { id: "ufw", version: "ubuntu-26.04" } },
722
- { requirement: { id: "openssh-client", version: "ubuntu-26.04" } }
723
+ { requirement: { id: "openssh-client", version: "ubuntu-26.04" } },
724
+ { requirement: { id: "git", version: "ubuntu-26.04" } }
723
725
  ];
724
726
  var path = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin";
725
727
  var DOCKER_DAEMON_PATH = "/etc/docker/daemon.json";
@@ -806,7 +808,7 @@ async function executeSoftwareOperation(operation) {
806
808
  const supported = observed && observed.some((part, index) => part > minimum[index] && observed.slice(0, index).every((prior, priorIndex) => prior === minimum[priorIndex])) || observed?.every((part, index) => part === minimum[index]);
807
809
  return { ...result, exitCode: result.exitCode === 0 && supported ? 0 : 1 };
808
810
  });
809
- const binaries = software === "ufw" ? ["/usr/sbin/ufw"] : ["/usr/bin/ssh", "/usr/bin/scp", "/usr/bin/ssh-keyscan", "/usr/bin/ssh-keygen"];
811
+ const binaries = software === "ufw" ? ["/usr/sbin/ufw"] : software === "git" ? ["/usr/bin/git"] : ["/usr/bin/ssh", "/usr/bin/scp", "/usr/bin/ssh-keyscan", "/usr/bin/ssh-keygen"];
810
812
  try {
811
813
  binaries.forEach((binary) => accessSync(binary));
812
814
  return { exitCode: 0, output: "" };
@@ -814,7 +816,7 @@ async function executeSoftwareOperation(operation) {
814
816
  return { exitCode: 1, output: cause instanceof Error ? cause.message : String(cause) };
815
817
  }
816
818
  }
817
- if (software === "docker" || software === "nginx" || software === "ufw" || software === "openssh-client") {
819
+ if (software === "docker" || software === "nginx" || software === "ufw" || software === "openssh-client" || software === "git") {
818
820
  const packageName = software === "openssh-client" ? "openssh-client" : software === "docker" ? "docker.io" : software;
819
821
  const installed = await aptInstall(packageName);
820
822
  if (installed.exitCode !== 0 || software !== "nginx" && software !== "docker")
@@ -914,7 +916,7 @@ function validateSoftwareRequirements(value, _options = {}) {
914
916
  if (Object.keys(row).some((key) => key !== "id" && key !== "version")) {
915
917
  throw new Error("software requirement contains an unknown field");
916
918
  }
917
- if (!["bun", "docker", "nginx", "arangodb", "cloudflared", "cloudflare-warp", "ufw", "openssh-client"].includes(String(row.id)) || typeof row.version !== "string" || !/^[A-Za-z0-9][A-Za-z0-9.-]{0,31}$/.test(row.version)) {
919
+ if (!["bun", "docker", "nginx", "arangodb", "cloudflared", "cloudflare-warp", "ufw", "openssh-client", "git"].includes(String(row.id)) || typeof row.version !== "string" || !/^[A-Za-z0-9][A-Za-z0-9.-]{0,31}$/.test(row.version)) {
918
920
  throw new Error("software requirement coordinate is invalid");
919
921
  }
920
922
  const requirement = { id: row.id, version: row.version };
@@ -2086,7 +2088,7 @@ function requestSoftware(requirements, socketPath = DEFAULT_SOFTWARE_HELPER_SOCK
2086
2088
  }
2087
2089
 
2088
2090
  // src/version.ts
2089
- var VERSION3 = "0.1.62";
2091
+ var VERSION3 = "0.1.63";
2090
2092
 
2091
2093
  // src/egress-policy.ts
2092
2094
  import { realpathSync as realpathSync3 } from "node:fs";
@@ -2215,7 +2217,11 @@ function agentEgressUnit(options) {
2215
2217
  const user = options.user ?? "forgezero";
2216
2218
  if (!/^[a-z_][a-z0-9_-]{0,30}$/.test(user))
2217
2219
  throw new Error("invalid Agent service user");
2218
- const deploymentEnabled = Boolean(options.repository || options.pullDeployments);
2220
+ const bootstrapBundleEnabled = Boolean(options.bootstrapBundlePath && options.bootstrapBundleManifestPath);
2221
+ if (Boolean(options.bootstrapBundlePath) !== Boolean(options.bootstrapBundleManifestPath) || bootstrapBundleEnabled && ![options.bootstrapBundlePath, options.bootstrapBundleManifestPath].every((path2) => path2.startsWith("/") && !/[\r\n\0:]/.test(path2))) {
2222
+ throw new Error("bootstrap bundle and manifest must be supplied together as absolute paths");
2223
+ }
2224
+ const deploymentEnabled = Boolean(options.repository || bootstrapBundleEnabled || options.pullDeployments);
2219
2225
  const runnerLoopbackPorts = normalizeEgressTcpPorts(options.runnerLoopbackPorts ?? []);
2220
2226
  const runnerPublicTcpPorts = normalizeEgressTcpPorts(options.runnerPublicTcpPorts ?? DEFAULT_RUNNER_PUBLIC_TCP_PORTS);
2221
2227
  if (deploymentEnabled && runnerPublicTcpPorts.length < 1) {
@@ -2685,6 +2691,8 @@ function agentUnit(options) {
2685
2691
  options.gitPublicKeyPath ? `FZ_GIT_PUBLIC_KEY_FILE=${options.gitPublicKeyPath}` : null,
2686
2692
  options.repository ? `FZ_DEPLOY_REPO=${options.repository}` : null,
2687
2693
  options.branch ? `FZ_DEPLOY_BRANCH=${options.branch}` : null,
2694
+ options.bootstrapBundlePath ? `FZ_BOOTSTRAP_BUNDLE=${options.bootstrapBundlePath}` : null,
2695
+ options.bootstrapBundleManifestPath ? `FZ_BOOTSTRAP_BUNDLE_MANIFEST=${options.bootstrapBundleManifestPath}` : null,
2688
2696
  options.profile ? `FZ_DEPLOY_PROFILE=${options.profile}` : null,
2689
2697
  options.repository && options.branch ? `FZ_DEPLOY_KEY=${options.project ?? "platform"}:${options.environment ?? "production"}` : null,
2690
2698
  deploymentEnabled ? `FZ_DEPLOY_ROOT=${deployRoot}` : null,
@@ -3168,8 +3176,6 @@ function validatePlatformSharedEnvironment(input) {
3168
3176
  databaseUser: input.databaseUser,
3169
3177
  sharedDirectory: input.sharedDirectory,
3170
3178
  seedSyncEpoch: input.seedSyncEpoch,
3171
- repository: input.repository,
3172
- branch: input.branch,
3173
3179
  deployProfile: input.deployProfile
3174
3180
  }))
3175
3181
  safeAtom(name, value);
@@ -3252,8 +3258,6 @@ function renderPlatformSharedEnvironment(input) {
3252
3258
  FZ_AGENT_OTLP_ENDPOINT: value.agentOtlpEndpoint,
3253
3259
  FZ_CUSTODIAN_EMAIL: value.custodianEmail ?? "",
3254
3260
  FZ_PROFILE: value.deployProfile,
3255
- FZ_REPO: value.repository,
3256
- FZ_BRANCH: value.branch,
3257
3261
  FZ_EMAIL_PROVIDER: value.email?.provider ?? "",
3258
3262
  FZ_SMTP_HOST: value.email?.provider === "smtp" ? value.email.host : "",
3259
3263
  FZ_SMTP_PORT: value.email?.provider === "smtp" ? String(value.email.port) : "",
@@ -3592,21 +3596,21 @@ function planLocalOtlpProof(endpoint, collectorUnit) {
3592
3596
  }
3593
3597
 
3594
3598
  // src/platform-fleet-verification.ts
3595
- import { lstatSync as lstatSync4 } from "node:fs";
3599
+ import { lstatSync as lstatSync5 } from "node:fs";
3596
3600
 
3597
3601
  // src/bootstrap.ts
3598
- import { createHash as createHash5, createHmac as createHmac2, randomBytes as randomBytes2 } from "node:crypto";
3602
+ import { createHash as createHash6, createHmac as createHmac2, randomBytes as randomBytes3 } from "node:crypto";
3599
3603
  import {
3600
- chmodSync as chmodSync7,
3601
- existsSync as existsSync9,
3602
- lstatSync as lstatSync3,
3603
- mkdirSync as mkdirSync9,
3604
- readFileSync as readFileSync8,
3605
- renameSync as renameSync8,
3606
- rmSync as rmSync8,
3607
- writeFileSync as writeFileSync8
3604
+ chmodSync as chmodSync8,
3605
+ existsSync as existsSync10,
3606
+ lstatSync as lstatSync4,
3607
+ mkdirSync as mkdirSync10,
3608
+ readFileSync as readFileSync9,
3609
+ renameSync as renameSync9,
3610
+ rmSync as rmSync9,
3611
+ writeFileSync as writeFileSync9
3608
3612
  } from "node:fs";
3609
- import { dirname as dirname8 } from "node:path";
3613
+ import { dirname as dirname9 } from "node:path";
3610
3614
  import { fileURLToPath } from "node:url";
3611
3615
 
3612
3616
  // src/cli/agent-install.ts
@@ -3918,6 +3922,58 @@ var UNIT = `/etc/systemd/system/${FORGEZERO_OTEL_COLLECTOR_UNIT}`;
3918
3922
 
3919
3923
  // src/bootstrap.ts
3920
3924
  import { DEFAULT_SOCKET as DEFAULT_SOCKET2 } from "@forgezero/vault";
3925
+
3926
+ // src/bootstrap-bundle.ts
3927
+ import { createHash as createHash5, randomBytes as randomBytes2 } from "node:crypto";
3928
+ import {
3929
+ chmodSync as chmodSync7,
3930
+ createReadStream,
3931
+ existsSync as existsSync9,
3932
+ lstatSync as lstatSync3,
3933
+ mkdirSync as mkdirSync9,
3934
+ readFileSync as readFileSync8,
3935
+ renameSync as renameSync8,
3936
+ rmSync as rmSync8,
3937
+ writeFileSync as writeFileSync8
3938
+ } from "node:fs";
3939
+ import { dirname as dirname8, isAbsolute, resolve as resolve6 } from "node:path";
3940
+ var BOOTSTRAP_BUNDLE_FORMAT = 1;
3941
+ var BOOTSTRAP_BUNDLE_KIND = "forgezero-api-git-bundle";
3942
+ var MAX_BOOTSTRAP_BUNDLE_BYTES = 512 * 1024 * 1024;
3943
+ var branchName = (value) => {
3944
+ if (typeof value !== "string" || !/^[A-Za-z0-9](?:[A-Za-z0-9._/-]{0,126}[A-Za-z0-9])?$/.test(value) || value.includes("..") || value.includes("//") || value.startsWith("-")) {
3945
+ throw new Error("bootstrap bundle branch is malformed");
3946
+ }
3947
+ return value;
3948
+ };
3949
+ function parseBootstrapBundleManifest(value) {
3950
+ if (!value || typeof value !== "object" || Array.isArray(value))
3951
+ throw new Error("bootstrap bundle manifest must be an object");
3952
+ const source = value;
3953
+ const allowed = ["format", "kind", "branch", "revision", "sha256", "bytes", "createdAt"];
3954
+ const unknown = Object.keys(source).filter((key) => !allowed.includes(key));
3955
+ if (unknown.length)
3956
+ throw new Error(`bootstrap bundle manifest contains unknown field ${unknown[0]}`);
3957
+ if (source.format !== BOOTSTRAP_BUNDLE_FORMAT || source.kind !== BOOTSTRAP_BUNDLE_KIND) {
3958
+ throw new Error("bootstrap bundle manifest format is unsupported");
3959
+ }
3960
+ branchName(source.branch);
3961
+ if (typeof source.revision !== "string" || !/^[a-f0-9]{40}$/.test(source.revision)) {
3962
+ throw new Error("bootstrap bundle revision must be an exact lowercase Git commit");
3963
+ }
3964
+ if (typeof source.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(source.sha256)) {
3965
+ throw new Error("bootstrap bundle digest is malformed");
3966
+ }
3967
+ if (!Number.isSafeInteger(source.bytes) || Number(source.bytes) < 1 || Number(source.bytes) > MAX_BOOTSTRAP_BUNDLE_BYTES) {
3968
+ throw new Error("bootstrap bundle size is outside the supported boundary");
3969
+ }
3970
+ if (typeof source.createdAt !== "string" || Number.isNaN(Date.parse(source.createdAt))) {
3971
+ throw new Error("bootstrap bundle creation time is malformed");
3972
+ }
3973
+ return source;
3974
+ }
3975
+
3976
+ // src/bootstrap.ts
3921
3977
  var platformBootstrapRunner = (config) => config.kind === "platform" && config.database.role === "master";
3922
3978
  var BOOTSTRAP_STATE_PATH = "/var/lib/forgezero/bootstrap.json";
3923
3979
  var STATE_PATH = BOOTSTRAP_STATE_PATH;
@@ -3934,6 +3990,7 @@ var SEED_CREDENTIAL = `${CREDS}/seed-sync-root.cred`;
3934
3990
  var BACKUP_RECOVERY_CREDENTIAL = `${CREDS}/backup-recovery-root.cred`;
3935
3991
  var BOOTSTRAP_SSH_CREDENTIAL = `${CREDS}/bootstrap-ssh-key.cred`;
3936
3992
  var BOOTSTRAP_SSH_PUBLIC_KEY = "/etc/forgezero/bootstrap/runner.pub";
3993
+ var BOOTSTRAP_RELEASE_EVIDENCE = "/var/lib/forgezero/bootstrap-release.json";
3937
3994
  var LIFECYCLE_PROFILE = "/etc/forgezero/lifecycle.json";
3938
3995
  var CONTROL_SOCKET = "/run/forgezero/control.sock";
3939
3996
  var CLOUDFLARED_METRICS_ADDRESS = "127.0.0.1:20241";
@@ -4126,19 +4183,19 @@ function localBootstrapHost() {
4126
4183
  };
4127
4184
  return {
4128
4185
  uid: () => process.getuid?.() ?? -1,
4129
- exists: existsSync9,
4130
- read: (path2) => readFileSync8(path2, "utf8"),
4186
+ exists: existsSync10,
4187
+ read: (path2) => readFileSync9(path2, "utf8"),
4131
4188
  write(path2, content, mode) {
4132
- mkdirSync9(dirname8(path2), { recursive: true, mode: 493 });
4189
+ mkdirSync10(dirname9(path2), { recursive: true, mode: 493 });
4133
4190
  const temporary = `${path2}.next.${process.pid}`;
4134
- writeFileSync8(temporary, content, { mode });
4135
- chmodSync7(temporary, mode);
4136
- renameSync8(temporary, path2);
4191
+ writeFileSync9(temporary, content, { mode });
4192
+ chmodSync8(temporary, mode);
4193
+ renameSync9(temporary, path2);
4137
4194
  },
4138
- mkdir: (path2, mode) => mkdirSync9(path2, { recursive: true, mode }),
4139
- remove: (path2) => rmSync8(path2, { force: true }),
4195
+ mkdir: (path2, mode) => mkdirSync10(path2, { recursive: true, mode }),
4196
+ remove: (path2) => rmSync9(path2, { force: true }),
4140
4197
  inspect(path2) {
4141
- const value = lstatSync3(path2);
4198
+ const value = lstatSync4(path2);
4142
4199
  return { regular: value.isFile(), symbolic: value.isSymbolicLink(), uid: value.uid, mode: value.mode, links: value.nlink, size: value.size };
4143
4200
  },
4144
4201
  exec: execute,
@@ -4160,7 +4217,12 @@ function localBootstrapHost() {
4160
4217
  async installAgent(config) {
4161
4218
  const capabilities = await readCapabilities(localRunner);
4162
4219
  const deployRoot = config.deployRoot ?? "/opt/forgezero";
4163
- const hasBinding = config.kind === "enrolled-compute" || existsSync9(ENROL_CREDENTIAL) || existsSync9("/var/lib/forgezero/enrolment.json");
4220
+ const hasBinding = existsSync10("/var/lib/forgezero/enrolment.json");
4221
+ const initialBundle = config.kind === "platform" && !existsSync10(BOOTSTRAP_RELEASE_EVIDENCE) ? {
4222
+ path: config.bootstrapBundle.bundleFile,
4223
+ manifestPath: config.bootstrapBundle.manifestFile,
4224
+ manifest: parseBootstrapBundleManifest(JSON.parse(readFileSync9(config.bootstrapBundle.manifestFile, "utf8")))
4225
+ } : undefined;
4164
4226
  if (config.kind === "platform") {
4165
4227
  const lifecycle = config.database.role === "none" ? {
4166
4228
  apiUnits: ["forgezero@blue.service", "forgezero@green.service"],
@@ -4172,8 +4234,8 @@ function localBootstrapHost() {
4172
4234
  databaseHealthUrl: `http://${config.database.address}:8529/_api/version`,
4173
4235
  databasePorts: [8529]
4174
4236
  };
4175
- mkdirSync9(dirname8(LIFECYCLE_PROFILE), { recursive: true, mode: 493 });
4176
- writeFileSync8(LIFECYCLE_PROFILE, `${JSON.stringify(lifecycle, null, 2)}
4237
+ mkdirSync10(dirname9(LIFECYCLE_PROFILE), { recursive: true, mode: 493 });
4238
+ writeFileSync9(LIFECYCLE_PROFILE, `${JSON.stringify(lifecycle, null, 2)}
4177
4239
  `, { mode: 256 });
4178
4240
  }
4179
4241
  const plan = planInstall({
@@ -4181,15 +4243,17 @@ function localBootstrapHost() {
4181
4243
  socketPath: DEFAULT_SOCKET2,
4182
4244
  seedPath: "/var/lib/forgezero/node.seed",
4183
4245
  controlSocketPath: "/run/forgezero/control.sock",
4184
- repository: config.repository,
4185
- branch: config.branch,
4246
+ repository: initialBundle?.path ?? (config.kind === "enrolled-compute" ? config.repository : undefined),
4247
+ branch: initialBundle?.manifest.branch ?? (config.kind === "enrolled-compute" ? config.branch : undefined),
4248
+ bootstrapBundlePath: initialBundle?.path,
4249
+ bootstrapBundleManifestPath: initialBundle?.manifestPath,
4186
4250
  profile: config.kind === "platform" ? config.profile : config.profile,
4187
4251
  deployRoot,
4188
4252
  deploymentCredentials: config.deploymentCredentials,
4189
4253
  publicApiUrl: config.apiUrl,
4190
- gitCredentialPath: "/etc/forgezero/creds/git-deploy-key.cred",
4191
- gitPublicKeyPath: "/etc/forgezero/git/deploy.pub",
4192
- generateGitIdentity: true,
4254
+ gitCredentialPath: config.kind === "enrolled-compute" && config.gitDeployKey ? "/etc/forgezero/creds/git-deploy-key.cred" : undefined,
4255
+ gitPublicKeyPath: config.kind === "enrolled-compute" && config.gitDeployKey ? "/etc/forgezero/git/deploy.pub" : undefined,
4256
+ generateGitIdentity: config.kind === "enrolled-compute" && config.gitDeployKey === true,
4193
4257
  pullDeployments: hasBinding,
4194
4258
  pullMigrations: config.kind === "platform" && hasBinding,
4195
4259
  pullBootstrap: platformBootstrapRunner(config) || config.kind === "enrolled-compute" && Boolean(config.bootstrapRunner),
@@ -4203,9 +4267,11 @@ function localBootstrapHost() {
4203
4267
  telemetryEndpoint: config.telemetryEndpoint,
4204
4268
  binPath: "/usr/local/lib/forgezero/agent/fz-agent",
4205
4269
  sourceBinPath: PACKAGED_AGENT_BIN,
4270
+ ...existsSync10(ENROL_CREDENTIAL) || hasBinding ? {
4271
+ enrolTokenCredentialPath: existsSync10(ENROL_CREDENTIAL) ? ENROL_CREDENTIAL : undefined,
4272
+ enrolStatePath: "/var/lib/forgezero/enrolment.json"
4273
+ } : {},
4206
4274
  ...hasBinding ? {
4207
- enrolTokenCredentialPath: ENROL_CREDENTIAL,
4208
- enrolStatePath: "/var/lib/forgezero/enrolment.json",
4209
4275
  apiUrl: config.apiUrl,
4210
4276
  project: config.kind === "enrolled-compute" ? config.realm : "platform",
4211
4277
  environment: config.kind === "enrolled-compute" ? undefined : config.environment,
@@ -4213,8 +4279,8 @@ function localBootstrapHost() {
4213
4279
  } : {}
4214
4280
  });
4215
4281
  for (const unit2 of [{ path: plan.unitPath, unit: plan.unit }, ...plan.auxiliaryUnits]) {
4216
- mkdirSync9(dirname8(unit2.path), { recursive: true, mode: 493 });
4217
- writeFileSync8(unit2.path, unit2.unit, { mode: 420 });
4282
+ mkdirSync10(dirname9(unit2.path), { recursive: true, mode: 493 });
4283
+ writeFileSync9(unit2.path, unit2.unit, { mode: 420 });
4218
4284
  }
4219
4285
  await applyPlan(plan, localRunner);
4220
4286
  return plan;
@@ -4228,7 +4294,7 @@ var localRuntime = () => ({
4228
4294
  bootstrapStatus: () => bootstrapStatus(),
4229
4295
  characterDevice(path2) {
4230
4296
  try {
4231
- return lstatSync4(path2).isCharacterDevice();
4297
+ return lstatSync5(path2).isCharacterDevice();
4232
4298
  } catch {
4233
4299
  return false;
4234
4300
  }
@@ -92,6 +92,9 @@ export interface UnitOptions {
92
92
  controlSocketPath?: string;
93
93
  repository?: string;
94
94
  branch?: string;
95
+ /** Attended release-generation-one artifact; both coordinates are required together. */
96
+ bootstrapBundlePath?: string;
97
+ bootstrapBundleManifestPath?: string;
95
98
  profile?: string;
96
99
  deployRoot?: string;
97
100
  publicApiUrl?: string;
@@ -164,7 +167,7 @@ export declare const WARP_SERVICE_DROP_IN_PATH = "/etc/systemd/system/warp-svc.s
164
167
  export declare const AGENT_EGRESS_UNIT_PATH = "/etc/systemd/system/forgezero-agent-egress.service";
165
168
  export declare const DEFAULT_RUNNER_PUBLIC_TCP_PORTS: readonly [443];
166
169
  /** Root-owned policy monitor. The credential-bearing Agent is bound to it. */
167
- export declare function agentEgressUnit(options: Pick<UnitOptions, 'binPath' | 'user' | 'repository' | 'pullDeployments' | 'runnerLoopbackPorts' | 'runnerPublicTcpPorts'>): string;
170
+ export declare function agentEgressUnit(options: Pick<UnitOptions, 'binPath' | 'user' | 'repository' | 'pullDeployments' | 'bootstrapBundlePath' | 'bootstrapBundleManifestPath' | 'runnerLoopbackPorts' | 'runnerPublicTcpPorts'>): string;
168
171
  /** Root may execute only package-owned OS strategies selected by id + version. */
169
172
  export declare function softwareHelperUnit(options: Pick<UnitOptions, 'binPath' | 'deployRoot'>): string;
170
173
  /** Fixed root boundary for verified, health-gated Agent replacement. */
package/dist/provision.js CHANGED
@@ -709,7 +709,8 @@ var SOFTWARE_CATALOG = [
709
709
  { id: "cloudflared", version: "2026.7.3", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
710
710
  { id: "cloudflare-warp", version: "2026.6.822.0-min", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
711
711
  { id: "ufw", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
712
- { id: "openssh-client", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" }
712
+ { id: "openssh-client", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
713
+ { id: "git", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" }
713
714
  ];
714
715
  var UBUNTU_2604_X64 = [
715
716
  { requirement: { id: "bun", version: "1.3.14" } },
@@ -719,7 +720,8 @@ var UBUNTU_2604_X64 = [
719
720
  { requirement: { id: "cloudflared", version: "2026.7.3" } },
720
721
  { requirement: { id: "cloudflare-warp", version: "2026.6.822.0-min" } },
721
722
  { requirement: { id: "ufw", version: "ubuntu-26.04" } },
722
- { requirement: { id: "openssh-client", version: "ubuntu-26.04" } }
723
+ { requirement: { id: "openssh-client", version: "ubuntu-26.04" } },
724
+ { requirement: { id: "git", version: "ubuntu-26.04" } }
723
725
  ];
724
726
  var path = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin";
725
727
  var DOCKER_DAEMON_PATH = "/etc/docker/daemon.json";
@@ -806,7 +808,7 @@ async function executeSoftwareOperation(operation) {
806
808
  const supported = observed && observed.some((part, index) => part > minimum[index] && observed.slice(0, index).every((prior, priorIndex) => prior === minimum[priorIndex])) || observed?.every((part, index) => part === minimum[index]);
807
809
  return { ...result, exitCode: result.exitCode === 0 && supported ? 0 : 1 };
808
810
  });
809
- const binaries = software === "ufw" ? ["/usr/sbin/ufw"] : ["/usr/bin/ssh", "/usr/bin/scp", "/usr/bin/ssh-keyscan", "/usr/bin/ssh-keygen"];
811
+ const binaries = software === "ufw" ? ["/usr/sbin/ufw"] : software === "git" ? ["/usr/bin/git"] : ["/usr/bin/ssh", "/usr/bin/scp", "/usr/bin/ssh-keyscan", "/usr/bin/ssh-keygen"];
810
812
  try {
811
813
  binaries.forEach((binary) => accessSync(binary));
812
814
  return { exitCode: 0, output: "" };
@@ -814,7 +816,7 @@ async function executeSoftwareOperation(operation) {
814
816
  return { exitCode: 1, output: cause instanceof Error ? cause.message : String(cause) };
815
817
  }
816
818
  }
817
- if (software === "docker" || software === "nginx" || software === "ufw" || software === "openssh-client") {
819
+ if (software === "docker" || software === "nginx" || software === "ufw" || software === "openssh-client" || software === "git") {
818
820
  const packageName = software === "openssh-client" ? "openssh-client" : software === "docker" ? "docker.io" : software;
819
821
  const installed = await aptInstall(packageName);
820
822
  if (installed.exitCode !== 0 || software !== "nginx" && software !== "docker")
@@ -914,7 +916,7 @@ function validateSoftwareRequirements(value, _options = {}) {
914
916
  if (Object.keys(row).some((key) => key !== "id" && key !== "version")) {
915
917
  throw new Error("software requirement contains an unknown field");
916
918
  }
917
- if (!["bun", "docker", "nginx", "arangodb", "cloudflared", "cloudflare-warp", "ufw", "openssh-client"].includes(String(row.id)) || typeof row.version !== "string" || !/^[A-Za-z0-9][A-Za-z0-9.-]{0,31}$/.test(row.version)) {
919
+ if (!["bun", "docker", "nginx", "arangodb", "cloudflared", "cloudflare-warp", "ufw", "openssh-client", "git"].includes(String(row.id)) || typeof row.version !== "string" || !/^[A-Za-z0-9][A-Za-z0-9.-]{0,31}$/.test(row.version)) {
918
920
  throw new Error("software requirement coordinate is invalid");
919
921
  }
920
922
  const requirement = { id: row.id, version: row.version };
@@ -2086,7 +2088,7 @@ function requestSoftware(requirements, socketPath = DEFAULT_SOFTWARE_HELPER_SOCK
2086
2088
  }
2087
2089
 
2088
2090
  // src/version.ts
2089
- var VERSION3 = "0.1.62";
2091
+ var VERSION3 = "0.1.63";
2090
2092
 
2091
2093
  // src/egress-policy.ts
2092
2094
  import { realpathSync as realpathSync3 } from "node:fs";
@@ -2215,7 +2217,11 @@ function agentEgressUnit(options) {
2215
2217
  const user = options.user ?? "forgezero";
2216
2218
  if (!/^[a-z_][a-z0-9_-]{0,30}$/.test(user))
2217
2219
  throw new Error("invalid Agent service user");
2218
- const deploymentEnabled = Boolean(options.repository || options.pullDeployments);
2220
+ const bootstrapBundleEnabled = Boolean(options.bootstrapBundlePath && options.bootstrapBundleManifestPath);
2221
+ if (Boolean(options.bootstrapBundlePath) !== Boolean(options.bootstrapBundleManifestPath) || bootstrapBundleEnabled && ![options.bootstrapBundlePath, options.bootstrapBundleManifestPath].every((path2) => path2.startsWith("/") && !/[\r\n\0:]/.test(path2))) {
2222
+ throw new Error("bootstrap bundle and manifest must be supplied together as absolute paths");
2223
+ }
2224
+ const deploymentEnabled = Boolean(options.repository || bootstrapBundleEnabled || options.pullDeployments);
2219
2225
  const runnerLoopbackPorts = normalizeEgressTcpPorts(options.runnerLoopbackPorts ?? []);
2220
2226
  const runnerPublicTcpPorts = normalizeEgressTcpPorts(options.runnerPublicTcpPorts ?? DEFAULT_RUNNER_PUBLIC_TCP_PORTS);
2221
2227
  if (deploymentEnabled && runnerPublicTcpPorts.length < 1) {
@@ -2685,6 +2691,8 @@ function agentUnit(options) {
2685
2691
  options.gitPublicKeyPath ? `FZ_GIT_PUBLIC_KEY_FILE=${options.gitPublicKeyPath}` : null,
2686
2692
  options.repository ? `FZ_DEPLOY_REPO=${options.repository}` : null,
2687
2693
  options.branch ? `FZ_DEPLOY_BRANCH=${options.branch}` : null,
2694
+ options.bootstrapBundlePath ? `FZ_BOOTSTRAP_BUNDLE=${options.bootstrapBundlePath}` : null,
2695
+ options.bootstrapBundleManifestPath ? `FZ_BOOTSTRAP_BUNDLE_MANIFEST=${options.bootstrapBundleManifestPath}` : null,
2688
2696
  options.profile ? `FZ_DEPLOY_PROFILE=${options.profile}` : null,
2689
2697
  options.repository && options.branch ? `FZ_DEPLOY_KEY=${options.project ?? "platform"}:${options.environment ?? "production"}` : null,
2690
2698
  deploymentEnabled ? `FZ_DEPLOY_ROOT=${deployRoot}` : null,
@@ -31,7 +31,8 @@ var SOFTWARE_CATALOG = [
31
31
  { id: "cloudflared", version: "2026.7.3", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
32
32
  { id: "cloudflare-warp", version: "2026.6.822.0-min", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
33
33
  { id: "ufw", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
34
- { id: "openssh-client", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" }
34
+ { id: "openssh-client", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
35
+ { id: "git", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" }
35
36
  ];
36
37
  var UBUNTU_2604_X64 = [
37
38
  { requirement: { id: "bun", version: "1.3.14" } },
@@ -41,7 +42,8 @@ var UBUNTU_2604_X64 = [
41
42
  { requirement: { id: "cloudflared", version: "2026.7.3" } },
42
43
  { requirement: { id: "cloudflare-warp", version: "2026.6.822.0-min" } },
43
44
  { requirement: { id: "ufw", version: "ubuntu-26.04" } },
44
- { requirement: { id: "openssh-client", version: "ubuntu-26.04" } }
45
+ { requirement: { id: "openssh-client", version: "ubuntu-26.04" } },
46
+ { requirement: { id: "git", version: "ubuntu-26.04" } }
45
47
  ];
46
48
  var path = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin";
47
49
  var DOCKER_DAEMON_PATH = "/etc/docker/daemon.json";
@@ -128,7 +130,7 @@ async function executeSoftwareOperation(operation) {
128
130
  const supported = observed && observed.some((part, index) => part > minimum[index] && observed.slice(0, index).every((prior, priorIndex) => prior === minimum[priorIndex])) || observed?.every((part, index) => part === minimum[index]);
129
131
  return { ...result, exitCode: result.exitCode === 0 && supported ? 0 : 1 };
130
132
  });
131
- const binaries = software === "ufw" ? ["/usr/sbin/ufw"] : ["/usr/bin/ssh", "/usr/bin/scp", "/usr/bin/ssh-keyscan", "/usr/bin/ssh-keygen"];
133
+ const binaries = software === "ufw" ? ["/usr/sbin/ufw"] : software === "git" ? ["/usr/bin/git"] : ["/usr/bin/ssh", "/usr/bin/scp", "/usr/bin/ssh-keyscan", "/usr/bin/ssh-keygen"];
132
134
  try {
133
135
  binaries.forEach((binary) => accessSync(binary));
134
136
  return { exitCode: 0, output: "" };
@@ -136,7 +138,7 @@ async function executeSoftwareOperation(operation) {
136
138
  return { exitCode: 1, output: cause instanceof Error ? cause.message : String(cause) };
137
139
  }
138
140
  }
139
- if (software === "docker" || software === "nginx" || software === "ufw" || software === "openssh-client") {
141
+ if (software === "docker" || software === "nginx" || software === "ufw" || software === "openssh-client" || software === "git") {
140
142
  const packageName = software === "openssh-client" ? "openssh-client" : software === "docker" ? "docker.io" : software;
141
143
  const installed = await aptInstall(packageName);
142
144
  if (installed.exitCode !== 0 || software !== "nginx" && software !== "docker")
@@ -236,7 +238,7 @@ function validateSoftwareRequirements(value, _options = {}) {
236
238
  if (Object.keys(row).some((key) => key !== "id" && key !== "version")) {
237
239
  throw new Error("software requirement contains an unknown field");
238
240
  }
239
- if (!["bun", "docker", "nginx", "arangodb", "cloudflared", "cloudflare-warp", "ufw", "openssh-client"].includes(String(row.id)) || typeof row.version !== "string" || !/^[A-Za-z0-9][A-Za-z0-9.-]{0,31}$/.test(row.version)) {
241
+ if (!["bun", "docker", "nginx", "arangodb", "cloudflared", "cloudflare-warp", "ufw", "openssh-client", "git"].includes(String(row.id)) || typeof row.version !== "string" || !/^[A-Za-z0-9][A-Za-z0-9.-]{0,31}$/.test(row.version)) {
240
242
  throw new Error("software requirement coordinate is invalid");
241
243
  }
242
244
  const requirement = { id: row.id, version: row.version };
@@ -1,6 +1,6 @@
1
1
  export type CatalogStatus = 'testing' | 'active' | 'retired';
2
2
  export type DeploymentChannel = 'development' | 'production';
3
- export type SoftwareId = 'bun' | 'docker' | 'nginx' | 'arangodb' | 'cloudflared' | 'cloudflare-warp' | 'ufw' | 'openssh-client';
3
+ export type SoftwareId = 'bun' | 'docker' | 'nginx' | 'arangodb' | 'cloudflared' | 'cloudflare-warp' | 'ufw' | 'openssh-client' | 'git';
4
4
  /** Repository input is a catalogue coordinate, never a root command. */
5
5
  export interface SoftwareRequirement {
6
6
  id: SoftwareId;
package/dist/software.js CHANGED
@@ -31,7 +31,8 @@ var SOFTWARE_CATALOG = [
31
31
  { id: "cloudflared", version: "2026.7.3", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
32
32
  { id: "cloudflare-warp", version: "2026.6.822.0-min", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
33
33
  { id: "ufw", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
34
- { id: "openssh-client", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" }
34
+ { id: "openssh-client", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
35
+ { id: "git", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" }
35
36
  ];
36
37
  var UBUNTU_2604_X64 = [
37
38
  { requirement: { id: "bun", version: "1.3.14" } },
@@ -41,7 +42,8 @@ var UBUNTU_2604_X64 = [
41
42
  { requirement: { id: "cloudflared", version: "2026.7.3" } },
42
43
  { requirement: { id: "cloudflare-warp", version: "2026.6.822.0-min" } },
43
44
  { requirement: { id: "ufw", version: "ubuntu-26.04" } },
44
- { requirement: { id: "openssh-client", version: "ubuntu-26.04" } }
45
+ { requirement: { id: "openssh-client", version: "ubuntu-26.04" } },
46
+ { requirement: { id: "git", version: "ubuntu-26.04" } }
45
47
  ];
46
48
  var path = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin";
47
49
  var DOCKER_DAEMON_PATH = "/etc/docker/daemon.json";
@@ -128,7 +130,7 @@ async function executeSoftwareOperation(operation) {
128
130
  const supported = observed && observed.some((part, index) => part > minimum[index] && observed.slice(0, index).every((prior, priorIndex) => prior === minimum[priorIndex])) || observed?.every((part, index) => part === minimum[index]);
129
131
  return { ...result, exitCode: result.exitCode === 0 && supported ? 0 : 1 };
130
132
  });
131
- const binaries = software === "ufw" ? ["/usr/sbin/ufw"] : ["/usr/bin/ssh", "/usr/bin/scp", "/usr/bin/ssh-keyscan", "/usr/bin/ssh-keygen"];
133
+ const binaries = software === "ufw" ? ["/usr/sbin/ufw"] : software === "git" ? ["/usr/bin/git"] : ["/usr/bin/ssh", "/usr/bin/scp", "/usr/bin/ssh-keyscan", "/usr/bin/ssh-keygen"];
132
134
  try {
133
135
  binaries.forEach((binary) => accessSync(binary));
134
136
  return { exitCode: 0, output: "" };
@@ -136,7 +138,7 @@ async function executeSoftwareOperation(operation) {
136
138
  return { exitCode: 1, output: cause instanceof Error ? cause.message : String(cause) };
137
139
  }
138
140
  }
139
- if (software === "docker" || software === "nginx" || software === "ufw" || software === "openssh-client") {
141
+ if (software === "docker" || software === "nginx" || software === "ufw" || software === "openssh-client" || software === "git") {
140
142
  const packageName = software === "openssh-client" ? "openssh-client" : software === "docker" ? "docker.io" : software;
141
143
  const installed = await aptInstall(packageName);
142
144
  if (installed.exitCode !== 0 || software !== "nginx" && software !== "docker")
@@ -236,7 +238,7 @@ function validateSoftwareRequirements(value, _options = {}) {
236
238
  if (Object.keys(row).some((key) => key !== "id" && key !== "version")) {
237
239
  throw new Error("software requirement contains an unknown field");
238
240
  }
239
- if (!["bun", "docker", "nginx", "arangodb", "cloudflared", "cloudflare-warp", "ufw", "openssh-client"].includes(String(row.id)) || typeof row.version !== "string" || !/^[A-Za-z0-9][A-Za-z0-9.-]{0,31}$/.test(row.version)) {
241
+ if (!["bun", "docker", "nginx", "arangodb", "cloudflared", "cloudflare-warp", "ufw", "openssh-client", "git"].includes(String(row.id)) || typeof row.version !== "string" || !/^[A-Za-z0-9][A-Za-z0-9.-]{0,31}$/.test(row.version)) {
240
242
  throw new Error("software requirement coordinate is invalid");
241
243
  }
242
244
  const requirement = { id: row.id, version: row.version };
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.62";
2
+ export declare const VERSION = "0.1.63";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forgezero/agent",
3
- "version": "0.1.62",
3
+ "version": "0.1.63",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "check": "tsc --noEmit",
@@ -56,6 +56,10 @@
56
56
  },
57
57
  "bugs": "https://github.com/forgezero-net/packages/issues",
58
58
  "exports": {
59
+ "./bootstrap-bundle": {
60
+ "types": "./dist/bootstrap-bundle.d.ts",
61
+ "default": "./dist/bootstrap-bundle.js"
62
+ },
59
63
  "./provision": {
60
64
  "types": "./dist/provision.d.ts",
61
65
  "default": "./dist/provision.js"