@forgezero/agent 0.1.65 → 0.1.68

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.
@@ -9,16 +9,22 @@ export interface SoftwareRequirement {
9
9
  export interface SoftwareCatalogEntry extends SoftwareRequirement {
10
10
  status: CatalogStatus;
11
11
  os: 'ubuntu';
12
- osVersion: '26.04';
12
+ osVersion: '24.04' | '26.04';
13
13
  architecture: 'x64';
14
14
  /** What promotes this coordinate beyond an unreviewed candidate. */
15
15
  evidence: 'reviewed-strategy-and-tests';
16
16
  }
17
17
  export interface OsCatalogEntry {
18
18
  id: 'ubuntu';
19
- version: '26.04';
19
+ version: '24.04' | '26.04';
20
20
  architecture: 'x64';
21
21
  status: CatalogStatus;
22
+ imageKey: 'ubuntu-noble-20260705' | 'ubuntu-resolute-20260731';
23
+ imageLabel: 'Ubuntu 24.04 LTS Noble' | 'Ubuntu 26.04 LTS Resolute';
24
+ imageVersion: '2026-07-05' | '2026-07-31';
25
+ imageUrl: string;
26
+ imageSha256: string;
27
+ confidentialModes: readonly [] | readonly ['sev-snp'];
22
28
  }
23
29
  export interface SoftwareObservation {
24
30
  os: {
package/dist/software.js CHANGED
@@ -21,7 +21,30 @@ var BUN_RELEASE_SHA256 = "951ee2aee855f08595aeec6225226a298d3fea83a3dcd6465c09cb
21
21
  var ARANGO_SHA256 = "b5a9197b4343f2ed554e1ebc1ef8e6529c7c39cde0035cdc311a4747a3355066";
22
22
  var CLOUDFLARED_SHA256 = "9d71c677db00134c1bd4144b7783486b654ad281b1ea62b4972098d19f770f17";
23
23
  var OS_CATALOG = [
24
- { id: "ubuntu", version: "26.04", architecture: "x64", status: "active" }
24
+ {
25
+ id: "ubuntu",
26
+ version: "26.04",
27
+ architecture: "x64",
28
+ status: "active",
29
+ imageKey: "ubuntu-resolute-20260731",
30
+ imageLabel: "Ubuntu 26.04 LTS Resolute",
31
+ imageVersion: "2026-07-31",
32
+ imageUrl: "https://cloud-images.ubuntu.com/releases/resolute/release-20260731/ubuntu-26.04-server-cloudimg-amd64.img",
33
+ imageSha256: "9dc7c5363c0146a08ba0c9aa834d82c2c6dfbb1c471ad9a2f0aba1189e21be05",
34
+ confidentialModes: ["sev-snp"]
35
+ },
36
+ {
37
+ id: "ubuntu",
38
+ version: "24.04",
39
+ architecture: "x64",
40
+ status: "active",
41
+ imageKey: "ubuntu-noble-20260705",
42
+ imageLabel: "Ubuntu 24.04 LTS Noble",
43
+ imageVersion: "2026-07-05",
44
+ imageUrl: "https://cloud-images.ubuntu.com/releases/noble/release-20260705/ubuntu-24.04-server-cloudimg-amd64.img",
45
+ imageSha256: "ffe6203da54deeb6db5d2a98a83f9ec8e55f149d3f7ba622e1abe5fa966ee3d6",
46
+ confidentialModes: []
47
+ }
25
48
  ];
26
49
  var SOFTWARE_CATALOG = [
27
50
  { id: "bun", version: "1.3.14", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
@@ -32,7 +55,12 @@ var SOFTWARE_CATALOG = [
32
55
  { id: "cloudflare-warp", version: "2026.6.822.0-min", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
33
56
  { id: "ufw", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
34
57
  { 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" }
58
+ { id: "git", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
59
+ { id: "docker", version: "ubuntu-24.04", status: "active", os: "ubuntu", osVersion: "24.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
60
+ { id: "nginx", version: "ubuntu-24.04", status: "active", os: "ubuntu", osVersion: "24.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
61
+ { id: "ufw", version: "ubuntu-24.04", status: "active", os: "ubuntu", osVersion: "24.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
62
+ { id: "openssh-client", version: "ubuntu-24.04", status: "active", os: "ubuntu", osVersion: "24.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
63
+ { id: "git", version: "ubuntu-24.04", status: "active", os: "ubuntu", osVersion: "24.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" }
36
64
  ];
37
65
  var UBUNTU_2604_X64 = [
38
66
  { requirement: { id: "bun", version: "1.3.14" } },
@@ -45,6 +73,15 @@ var UBUNTU_2604_X64 = [
45
73
  { requirement: { id: "openssh-client", version: "ubuntu-26.04" } },
46
74
  { requirement: { id: "git", version: "ubuntu-26.04" } }
47
75
  ];
76
+ var UBUNTU_2404_X64 = [
77
+ { requirement: { id: "bun", version: "1.3.14" } },
78
+ { requirement: { id: "docker", version: "ubuntu-24.04" } },
79
+ { requirement: { id: "nginx", version: "ubuntu-24.04" } },
80
+ { requirement: { id: "ufw", version: "ubuntu-24.04" } },
81
+ { requirement: { id: "openssh-client", version: "ubuntu-24.04" } },
82
+ { requirement: { id: "git", version: "ubuntu-24.04" } }
83
+ ];
84
+ var strategiesFor = (observation) => observation.os.id === "ubuntu" && observation.architecture === "x64" ? observation.os.versionId === "26.04" ? UBUNTU_2604_X64 : observation.os.versionId === "24.04" ? UBUNTU_2404_X64 : undefined : undefined;
48
85
  var path = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin";
49
86
  var DOCKER_DAEMON_PATH = "/etc/docker/daemon.json";
50
87
  var DOCKER_DAEMON_CONFIG = `${JSON.stringify({
@@ -91,7 +128,7 @@ var aptInstall = async (name) => {
91
128
  };
92
129
  async function executeSoftwareOperation(operation) {
93
130
  const { software, version } = operation;
94
- if (!UBUNTU_2604_X64.some(({ requirement }) => requirement.id === software && requirement.version === version)) {
131
+ if (![...UBUNTU_2604_X64, ...UBUNTU_2404_X64].some(({ requirement }) => requirement.id === software && requirement.version === version)) {
95
132
  return { exitCode: 2, output: "unsupported software operation" };
96
133
  }
97
134
  if (operation.kind === "check") {
@@ -261,7 +298,7 @@ async function ensureSoftwareRequirements(requirementsInput, options) {
261
298
  }
262
299
  const results = [];
263
300
  for (const requirement of requirements) {
264
- const strategy = UBUNTU_2604_X64.find(({ requirement: candidate }) => candidate.id === requirement.id && candidate.version === requirement.version);
301
+ const strategy = strategiesFor(observation)?.find(({ requirement: candidate }) => candidate.id === requirement.id && candidate.version === requirement.version);
265
302
  if (!strategy)
266
303
  throw new Error(`unsupported software requirement: ${requirement.id}@${requirement.version}`);
267
304
  const before = await options.exec({ kind: "check", software: requirement.id, version: requirement.version });
@@ -16,6 +16,11 @@ export interface RemoteSshBootstrapClaim {
16
16
  user: string;
17
17
  hostKeySha256: string;
18
18
  nodeHostname: string;
19
+ operatingSystem: {
20
+ id: 'ubuntu';
21
+ version: '24.04' | '26.04';
22
+ architecture: 'x64';
23
+ };
19
24
  credential: {
20
25
  source: 'runner';
21
26
  } | {
package/dist/ubuntu.d.ts CHANGED
@@ -1,16 +1,17 @@
1
- /**
2
- * The only guest operating system ForgeZero currently supports.
3
- *
4
- * A dated Canonical release directory and its published SHA-256 make image
5
- * acquisition reproducible. `release/current` is deliberately forbidden: it
6
- * changes underneath an already reviewed metal profile.
7
- */
8
1
  export declare const SUPPORTED_GUEST_IMAGE: Readonly<{
9
- readonly key: "ubuntu-resolute-20260731";
10
- readonly family: "ubuntu-26.04";
11
- readonly version: "2026-07-31";
12
- readonly label: "Ubuntu 26.04 LTS Resolute";
13
- readonly url: "https://cloud-images.ubuntu.com/releases/resolute/release-20260731/ubuntu-26.04-server-cloudimg-amd64.img";
14
- readonly sha256: "9dc7c5363c0146a08ba0c9aa834d82c2c6dfbb1c471ad9a2f0aba1189e21be05";
2
+ key: "ubuntu-noble-20260705" | "ubuntu-resolute-20260731";
3
+ family: "ubuntu-26.04" | "ubuntu-24.04";
4
+ version: "2026-07-05" | "2026-07-31";
5
+ label: "Ubuntu 24.04 LTS Noble" | "Ubuntu 26.04 LTS Resolute";
6
+ url: string;
7
+ sha256: string;
15
8
  }>;
16
- export declare function assertSupportedGuestImage(imageKey: string): void;
9
+ export declare const SUPPORTED_GUEST_IMAGES: readonly {
10
+ key: "ubuntu-noble-20260705" | "ubuntu-resolute-20260731";
11
+ label: "Ubuntu 24.04 LTS Noble" | "Ubuntu 26.04 LTS Resolute";
12
+ family: string;
13
+ version: "2026-07-05" | "2026-07-31";
14
+ confidential: boolean;
15
+ }[];
16
+ export declare function supportedGuestImage(imageKey: string): (typeof SUPPORTED_GUEST_IMAGES)[number] | undefined;
17
+ export declare function assertSupportedGuestImage(imageKey: string, confidential?: boolean): void;
package/dist/ubuntu.js CHANGED
@@ -1,18 +1,354 @@
1
+ // src/software.ts
2
+ import { createHash } from "node:crypto";
3
+ import {
4
+ accessSync,
5
+ chmodSync,
6
+ copyFileSync,
7
+ existsSync,
8
+ mkdtempSync,
9
+ mkdirSync,
10
+ readFileSync,
11
+ renameSync,
12
+ rmSync,
13
+ symlinkSync,
14
+ unlinkSync,
15
+ writeFileSync
16
+ } from "node:fs";
17
+ import { tmpdir } from "node:os";
18
+ import { join } from "node:path";
19
+ var PINNED_BUN_VERSION = "1.3.14";
20
+ var BUN_RELEASE_SHA256 = "951ee2aee855f08595aeec6225226a298d3fea83a3dcd6465c09cbccdf7e848f";
21
+ var ARANGO_SHA256 = "b5a9197b4343f2ed554e1ebc1ef8e6529c7c39cde0035cdc311a4747a3355066";
22
+ var CLOUDFLARED_SHA256 = "9d71c677db00134c1bd4144b7783486b654ad281b1ea62b4972098d19f770f17";
23
+ var OS_CATALOG = [
24
+ {
25
+ id: "ubuntu",
26
+ version: "26.04",
27
+ architecture: "x64",
28
+ status: "active",
29
+ imageKey: "ubuntu-resolute-20260731",
30
+ imageLabel: "Ubuntu 26.04 LTS Resolute",
31
+ imageVersion: "2026-07-31",
32
+ imageUrl: "https://cloud-images.ubuntu.com/releases/resolute/release-20260731/ubuntu-26.04-server-cloudimg-amd64.img",
33
+ imageSha256: "9dc7c5363c0146a08ba0c9aa834d82c2c6dfbb1c471ad9a2f0aba1189e21be05",
34
+ confidentialModes: ["sev-snp"]
35
+ },
36
+ {
37
+ id: "ubuntu",
38
+ version: "24.04",
39
+ architecture: "x64",
40
+ status: "active",
41
+ imageKey: "ubuntu-noble-20260705",
42
+ imageLabel: "Ubuntu 24.04 LTS Noble",
43
+ imageVersion: "2026-07-05",
44
+ imageUrl: "https://cloud-images.ubuntu.com/releases/noble/release-20260705/ubuntu-24.04-server-cloudimg-amd64.img",
45
+ imageSha256: "ffe6203da54deeb6db5d2a98a83f9ec8e55f149d3f7ba622e1abe5fa966ee3d6",
46
+ confidentialModes: []
47
+ }
48
+ ];
49
+ var SOFTWARE_CATALOG = [
50
+ { id: "bun", version: "1.3.14", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
51
+ { id: "docker", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
52
+ { id: "nginx", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
53
+ { id: "arangodb", version: "3.11.14", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
54
+ { id: "cloudflared", version: "2026.7.3", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
55
+ { id: "cloudflare-warp", version: "2026.6.822.0-min", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
56
+ { id: "ufw", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
57
+ { id: "openssh-client", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
58
+ { id: "git", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
59
+ { id: "docker", version: "ubuntu-24.04", status: "active", os: "ubuntu", osVersion: "24.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
60
+ { id: "nginx", version: "ubuntu-24.04", status: "active", os: "ubuntu", osVersion: "24.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
61
+ { id: "ufw", version: "ubuntu-24.04", status: "active", os: "ubuntu", osVersion: "24.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
62
+ { id: "openssh-client", version: "ubuntu-24.04", status: "active", os: "ubuntu", osVersion: "24.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
63
+ { id: "git", version: "ubuntu-24.04", status: "active", os: "ubuntu", osVersion: "24.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" }
64
+ ];
65
+ var UBUNTU_2604_X64 = [
66
+ { requirement: { id: "bun", version: "1.3.14" } },
67
+ { requirement: { id: "docker", version: "ubuntu-26.04" } },
68
+ { requirement: { id: "nginx", version: "ubuntu-26.04" } },
69
+ { requirement: { id: "arangodb", version: "3.11.14" } },
70
+ { requirement: { id: "cloudflared", version: "2026.7.3" } },
71
+ { requirement: { id: "cloudflare-warp", version: "2026.6.822.0-min" } },
72
+ { requirement: { id: "ufw", version: "ubuntu-26.04" } },
73
+ { requirement: { id: "openssh-client", version: "ubuntu-26.04" } },
74
+ { requirement: { id: "git", version: "ubuntu-26.04" } }
75
+ ];
76
+ var UBUNTU_2404_X64 = [
77
+ { requirement: { id: "bun", version: "1.3.14" } },
78
+ { requirement: { id: "docker", version: "ubuntu-24.04" } },
79
+ { requirement: { id: "nginx", version: "ubuntu-24.04" } },
80
+ { requirement: { id: "ufw", version: "ubuntu-24.04" } },
81
+ { requirement: { id: "openssh-client", version: "ubuntu-24.04" } },
82
+ { requirement: { id: "git", version: "ubuntu-24.04" } }
83
+ ];
84
+ var strategiesFor = (observation) => observation.os.id === "ubuntu" && observation.architecture === "x64" ? observation.os.versionId === "26.04" ? UBUNTU_2604_X64 : observation.os.versionId === "24.04" ? UBUNTU_2404_X64 : undefined : undefined;
85
+ var path = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin";
86
+ var DOCKER_DAEMON_PATH = "/etc/docker/daemon.json";
87
+ var DOCKER_DAEMON_CONFIG = `${JSON.stringify({
88
+ "data-root": "/var/lib/docker",
89
+ "storage-driver": "overlay2",
90
+ "live-restore": true,
91
+ "log-driver": "local",
92
+ "log-opts": { "max-size": "10m", "max-file": "3" }
93
+ }, null, 2)}
94
+ `;
95
+ var softwareSpawnFailure = (cause, argv) => cause.code === "ENOENT" ? { exitCode: 127, output: `executable is absent: ${argv[0]}` } : undefined;
96
+ var runSoftwareCommand = async (argv, env = {}) => {
97
+ let child;
98
+ try {
99
+ child = Bun.spawn([...argv], { stdout: "pipe", stderr: "pipe", env: { PATH: path, LANG: "C", LC_ALL: "C", ...env } });
100
+ } catch (cause) {
101
+ const failure = softwareSpawnFailure(cause, argv);
102
+ if (failure)
103
+ return failure;
104
+ throw cause;
105
+ }
106
+ const [stdout, stderr, exitCode] = await Promise.all([
107
+ new Response(child.stdout).text(),
108
+ new Response(child.stderr).text(),
109
+ child.exited
110
+ ]);
111
+ return { exitCode, output: `${stdout}${stderr}` };
112
+ };
113
+ var run = runSoftwareCommand;
114
+ var download = async (url, destination, sha256) => {
115
+ const response = await fetch(url, { redirect: "follow", signal: AbortSignal.timeout(120000) });
116
+ if (!response.ok)
117
+ throw new Error(`download failed with HTTP ${response.status}`);
118
+ const bytes = new Uint8Array(await response.arrayBuffer());
119
+ if (createHash("sha256").update(bytes).digest("hex") !== sha256)
120
+ throw new Error("download checksum mismatch");
121
+ writeFileSync(destination, bytes, { mode: 384, flag: "wx" });
122
+ };
123
+ var successful = (result, pattern) => result.exitCode === 0 && (!pattern || pattern.test(result.output));
124
+ var aptInstall = async (name) => {
125
+ const environment = { DEBIAN_FRONTEND: "noninteractive" };
126
+ const update = await run(["/usr/bin/apt-get", "update", "-qq"], environment);
127
+ return update.exitCode === 0 ? run(["/usr/bin/apt-get", "install", "-y", name], environment) : update;
128
+ };
129
+ async function executeSoftwareOperation(operation) {
130
+ const { software, version } = operation;
131
+ if (![...UBUNTU_2604_X64, ...UBUNTU_2404_X64].some(({ requirement }) => requirement.id === software && requirement.version === version)) {
132
+ return { exitCode: 2, output: "unsupported software operation" };
133
+ }
134
+ if (operation.kind === "check") {
135
+ if (software === "bun")
136
+ return run(["/usr/local/bin/bun", "--version"]).then((r) => ({ ...r, exitCode: successful(r, /^1\.3\.14\s*$/m) ? 0 : 1 }));
137
+ if (software === "docker") {
138
+ const binary = await run(["/usr/bin/docker", "--version"]);
139
+ if (!successful(binary, /Docker version/))
140
+ return { ...binary, exitCode: 1 };
141
+ if (!existsSync(DOCKER_DAEMON_PATH) || readFileSync(DOCKER_DAEMON_PATH, "utf8") !== DOCKER_DAEMON_CONFIG)
142
+ return { exitCode: 1, output: "Docker daemon policy is absent or differs from the reviewed ForgeZero policy" };
143
+ const active = await run(["/usr/bin/systemctl", "is-active", "--quiet", "docker.service"]);
144
+ return active.exitCode === 0 ? { exitCode: 0, output: binary.output } : active;
145
+ }
146
+ if (software === "nginx") {
147
+ const binary = await run(["/usr/sbin/nginx", "-v"]);
148
+ return binary.exitCode === 0 ? run(["/usr/bin/systemctl", "is-active", "--quiet", "nginx.service"]) : binary;
149
+ }
150
+ if (software === "arangodb") {
151
+ const binary = await run(["/usr/sbin/arangod", "--version"]);
152
+ if (!successful(binary, /3\.11\.14/))
153
+ return { ...binary, exitCode: 1 };
154
+ const [active, enabled] = await Promise.all([
155
+ run(["/usr/bin/systemctl", "is-active", "--quiet", "arangodb3.service"]),
156
+ run(["/usr/bin/systemctl", "is-enabled", "--quiet", "arangodb3.service"])
157
+ ]);
158
+ return active.exitCode !== 0 && enabled.exitCode !== 0 ? { exitCode: 0, output: binary.output } : { exitCode: 1, output: "vendor standalone unit remains active or enabled" };
159
+ }
160
+ if (software === "cloudflared")
161
+ return run(["/usr/local/bin/cloudflared", "--version"]).then((r) => ({ ...r, exitCode: successful(r, /2026\.7\.3/) ? 0 : 1 }));
162
+ if (software === "cloudflare-warp")
163
+ return run(["/usr/bin/warp-cli", "--version"]).then((result) => {
164
+ const match = result.output.match(/(\d{4})\.(\d+)\.(\d+)\.(\d+)/);
165
+ const observed = match?.slice(1).map(Number);
166
+ const minimum = [2026, 6, 822, 0];
167
+ 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]);
168
+ return { ...result, exitCode: result.exitCode === 0 && supported ? 0 : 1 };
169
+ });
170
+ 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"];
171
+ try {
172
+ binaries.forEach((binary) => accessSync(binary));
173
+ return { exitCode: 0, output: "" };
174
+ } catch (cause) {
175
+ return { exitCode: 1, output: cause instanceof Error ? cause.message : String(cause) };
176
+ }
177
+ }
178
+ if (software === "docker" || software === "nginx" || software === "ufw" || software === "openssh-client" || software === "git") {
179
+ const packageName = software === "openssh-client" ? "openssh-client" : software === "docker" ? "docker.io" : software;
180
+ const installed = await aptInstall(packageName);
181
+ if (installed.exitCode !== 0 || software !== "nginx" && software !== "docker")
182
+ return installed;
183
+ if (software === "docker") {
184
+ mkdirSync("/etc/docker", { recursive: true, mode: 493 });
185
+ if (existsSync(DOCKER_DAEMON_PATH) && readFileSync(DOCKER_DAEMON_PATH, "utf8") !== DOCKER_DAEMON_CONFIG) {
186
+ return { exitCode: 2, output: "refusing to overwrite an existing Docker daemon configuration that differs from the reviewed ForgeZero policy" };
187
+ }
188
+ if (!existsSync(DOCKER_DAEMON_PATH))
189
+ writeFileSync(DOCKER_DAEMON_PATH, DOCKER_DAEMON_CONFIG, { mode: 420, flag: "wx" });
190
+ const enabled = await run(["/usr/bin/systemctl", "enable", "docker.service"]);
191
+ return enabled.exitCode === 0 ? run(["/usr/bin/systemctl", "restart", "docker.service"]) : enabled;
192
+ }
193
+ return run(["/usr/bin/systemctl", "enable", "--now", `${software}.service`]);
194
+ }
195
+ const directory = mkdtempSync(join(tmpdir(), "forgezero-software-"));
196
+ try {
197
+ if (software === "cloudflare-warp") {
198
+ const key = join(directory, "cloudflare-warp-key.gpg");
199
+ await download("https://pkg.cloudflareclient.com/pubkey.gpg", key, "0f37fc298c98e88ee3c0ee68c95b69f1dba9eb477abe3167e13982105911264d");
200
+ mkdirSync("/usr/share/keyrings", { recursive: true, mode: 493 });
201
+ const dearmored = await run([
202
+ "/usr/bin/gpg",
203
+ "--batch",
204
+ "--yes",
205
+ "--dearmor",
206
+ "-o",
207
+ "/usr/share/keyrings/cloudflare-warp-archive-keyring.gpg",
208
+ key
209
+ ]);
210
+ if (dearmored.exitCode !== 0)
211
+ return dearmored;
212
+ mkdirSync("/etc/apt/sources.list.d", { recursive: true, mode: 493 });
213
+ writeFileSync("/etc/apt/sources.list.d/cloudflare-client.list", `deb [signed-by=/usr/share/keyrings/cloudflare-warp-archive-keyring.gpg] https://pkg.cloudflareclient.com/ resolute main
214
+ `, { mode: 420 });
215
+ return aptInstall("cloudflare-warp");
216
+ }
217
+ if (software === "bun") {
218
+ const archive = join(directory, "bun.zip");
219
+ await download("https://github.com/oven-sh/bun/releases/download/bun-v1.3.14/bun-linux-x64.zip", archive, BUN_RELEASE_SHA256);
220
+ const unpacked = join(directory, "unpacked");
221
+ mkdirSync(unpacked, { mode: 448 });
222
+ const unzipped = await run(["/usr/bin/unzip", "-q", archive, "-d", unpacked]);
223
+ if (unzipped.exitCode !== 0)
224
+ return unzipped;
225
+ mkdirSync("/usr/local/lib/forgezero/runtime", { recursive: true, mode: 493 });
226
+ copyFileSync(join(unpacked, "bun-linux-x64", "bun"), "/usr/local/lib/forgezero/runtime/bun.next");
227
+ chmodSync("/usr/local/lib/forgezero/runtime/bun.next", 493);
228
+ renameSync("/usr/local/lib/forgezero/runtime/bun.next", "/usr/local/lib/forgezero/runtime/bun");
229
+ try {
230
+ unlinkSync("/usr/local/bin/bun");
231
+ } catch {}
232
+ symlinkSync("/usr/local/lib/forgezero/runtime/bun", "/usr/local/bin/bun");
233
+ return { exitCode: 0, output: "" };
234
+ }
235
+ if (software === "cloudflared") {
236
+ const binary = join(directory, "cloudflared");
237
+ await download("https://github.com/cloudflare/cloudflared/releases/download/2026.7.3/cloudflared-linux-amd64", binary, CLOUDFLARED_SHA256);
238
+ chmodSync(binary, 493);
239
+ copyFileSync(binary, "/usr/local/bin/cloudflared");
240
+ chmodSync("/usr/local/bin/cloudflared", 493);
241
+ return { exitCode: 0, output: "" };
242
+ }
243
+ const deb = join(directory, "arangodb.deb");
244
+ await download("https://download.arangodb.com/arangodb311/DEBIAN/amd64/arangodb3_3.11.14-1_amd64.deb", deb, ARANGO_SHA256);
245
+ let installed = await run(["/usr/bin/dpkg", "-i", deb], { DEBIAN_FRONTEND: "noninteractive" });
246
+ if (installed.exitCode !== 0)
247
+ installed = await run(["/usr/bin/apt-get", "-y", "-f", "install"], { DEBIAN_FRONTEND: "noninteractive" });
248
+ if (installed.exitCode !== 0)
249
+ return installed;
250
+ await run(["/usr/bin/systemctl", "disable", "--now", "arangodb3.service"]);
251
+ return { exitCode: 0, output: "" };
252
+ } finally {
253
+ rmSync(directory, { recursive: true, force: true });
254
+ }
255
+ }
256
+ function observeSoftwareHost(osRelease = readFileSync("/etc/os-release", "utf8"), architecture = process.arch) {
257
+ const values = Object.fromEntries(osRelease.split(`
258
+ `).flatMap((line) => {
259
+ const separator = line.indexOf("=");
260
+ return separator > 0 ? [[line.slice(0, separator), line.slice(separator + 1).replace(/^['"]|['"]$/g, "")]] : [];
261
+ }));
262
+ return {
263
+ os: { id: (values.ID ?? "unknown").toLowerCase(), versionId: values.VERSION_ID ?? "unknown" },
264
+ architecture
265
+ };
266
+ }
267
+ function validateSoftwareRequirements(value, _options = {}) {
268
+ if (!Array.isArray(value) || value.length > 32)
269
+ throw new Error("software requirements must be an array of at most 32 entries");
270
+ const seen = new Set;
271
+ return value.map((item) => {
272
+ if (!item || typeof item !== "object" || Array.isArray(item))
273
+ throw new Error("software requirement must be an object");
274
+ const row = item;
275
+ if (Object.keys(row).some((key) => key !== "id" && key !== "version")) {
276
+ throw new Error("software requirement contains an unknown field");
277
+ }
278
+ 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)) {
279
+ throw new Error("software requirement coordinate is invalid");
280
+ }
281
+ const requirement = { id: row.id, version: row.version };
282
+ if (seen.has(requirement.id))
283
+ throw new Error(`duplicate software requirement: ${requirement.id}`);
284
+ seen.add(requirement.id);
285
+ const catalog = SOFTWARE_CATALOG.find((candidate) => candidate.id === requirement.id && candidate.version === requirement.version);
286
+ if (!catalog || catalog.status !== "active") {
287
+ throw new Error(`software requirement is not active: ${requirement.id}@${requirement.version}`);
288
+ }
289
+ return requirement;
290
+ });
291
+ }
292
+ async function ensureSoftwareRequirements(requirementsInput, options) {
293
+ const requirements = validateSoftwareRequirements(requirementsInput);
294
+ const observation = options.observation ?? observeSoftwareHost();
295
+ const os = OS_CATALOG.find((candidate) => candidate.id === observation.os.id && candidate.version === observation.os.versionId && candidate.architecture === observation.architecture);
296
+ if (!os || os.status !== "active") {
297
+ throw new Error(`unsupported software strategy: ${observation.os.id} ${observation.os.versionId} ${observation.architecture}`);
298
+ }
299
+ const results = [];
300
+ for (const requirement of requirements) {
301
+ const strategy = strategiesFor(observation)?.find(({ requirement: candidate }) => candidate.id === requirement.id && candidate.version === requirement.version);
302
+ if (!strategy)
303
+ throw new Error(`unsupported software requirement: ${requirement.id}@${requirement.version}`);
304
+ const before = await options.exec({ kind: "check", software: requirement.id, version: requirement.version });
305
+ if (before.exitCode === 0) {
306
+ results.push({ ...requirement, changed: false });
307
+ continue;
308
+ }
309
+ const installed = await options.exec({ kind: "install", software: requirement.id, version: requirement.version });
310
+ if (installed.exitCode !== 0)
311
+ throw new Error(`could not install ${requirement.id}@${requirement.version}: ${installed.output.trim()}`);
312
+ const after = await options.exec({ kind: "check", software: requirement.id, version: requirement.version });
313
+ if (after.exitCode !== 0)
314
+ throw new Error(`${requirement.id}@${requirement.version} did not pass its post-install check`);
315
+ results.push({ ...requirement, changed: true });
316
+ }
317
+ return results;
318
+ }
319
+
1
320
  // src/ubuntu.ts
321
+ var current = OS_CATALOG[0];
2
322
  var SUPPORTED_GUEST_IMAGE = Object.freeze({
3
- key: "ubuntu-resolute-20260731",
4
- family: "ubuntu-26.04",
5
- version: "2026-07-31",
6
- label: "Ubuntu 26.04 LTS Resolute",
7
- url: "https://cloud-images.ubuntu.com/releases/resolute/release-20260731/ubuntu-26.04-server-cloudimg-amd64.img",
8
- sha256: "9dc7c5363c0146a08ba0c9aa834d82c2c6dfbb1c471ad9a2f0aba1189e21be05"
323
+ key: current.imageKey,
324
+ family: `${current.id}-${current.version}`,
325
+ version: current.imageVersion,
326
+ label: current.imageLabel,
327
+ url: current.imageUrl,
328
+ sha256: current.imageSha256
9
329
  });
10
- function assertSupportedGuestImage(imageKey) {
11
- if (imageKey !== SUPPORTED_GUEST_IMAGE.key) {
12
- throw new Error(`unsupported guest image ${imageKey}; ForgeZero currently supports only ${SUPPORTED_GUEST_IMAGE.key}`);
330
+ var SUPPORTED_GUEST_IMAGES = Object.freeze(OS_CATALOG.filter(({ status }) => status === "active").map(({ id, imageKey, imageLabel, imageVersion, version, confidentialModes }) => ({
331
+ key: imageKey,
332
+ label: imageLabel,
333
+ family: `${id}-${version}`,
334
+ version: imageVersion,
335
+ confidential: confidentialModes.some((mode) => mode === "sev-snp")
336
+ })));
337
+ function supportedGuestImage(imageKey) {
338
+ return SUPPORTED_GUEST_IMAGES.find(({ key }) => key === imageKey);
339
+ }
340
+ function assertSupportedGuestImage(imageKey, confidential = false) {
341
+ const selected = OS_CATALOG.find((entry) => entry.status === "active" && entry.imageKey === imageKey);
342
+ if (!selected) {
343
+ throw new Error(`unsupported guest image ${imageKey}; supported images: ${SUPPORTED_GUEST_IMAGES.map(({ key }) => key).join(", ")}`);
344
+ }
345
+ if (confidential && !selected.confidentialModes.some((mode) => mode === "sev-snp")) {
346
+ throw new Error(`guest image ${imageKey} is not approved for SEV-SNP`);
13
347
  }
14
348
  }
15
349
  export {
350
+ supportedGuestImage,
16
351
  assertSupportedGuestImage,
352
+ SUPPORTED_GUEST_IMAGES,
17
353
  SUPPORTED_GUEST_IMAGE
18
354
  };
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.65";
2
+ export declare const VERSION = "0.1.68";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forgezero/agent",
3
- "version": "0.1.65",
3
+ "version": "0.1.68",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "check": "tsc --noEmit",
@@ -11,13 +11,13 @@
11
11
  "typescript": "^5.6.0",
12
12
  "@types/bun": "latest",
13
13
  "@types/node": "^22.0.0",
14
- "@forgezero/access": "0.1.4",
14
+ "@forgezero/access": "0.1.5",
15
15
  "@noble/curves": "^2.2.0",
16
16
  "@noble/post-quantum": "^0.6.1"
17
17
  },
18
18
  "dependencies": {
19
- "@forgezero/runtime": "0.1.8",
20
- "@forgezero/vault": "0.1.12",
19
+ "@forgezero/runtime": "0.1.9",
20
+ "@forgezero/vault": "0.1.13",
21
21
  "@noble/curves": "2.2.0",
22
22
  "@noble/hashes": "2.2.0",
23
23
  "@noble/post-quantum": "0.6.1",
@@ -153,6 +153,10 @@
153
153
  "types": "./dist/metal-provision.d.ts",
154
154
  "default": "./dist/metal-provision.js"
155
155
  },
156
+ "./platform-genesis": {
157
+ "types": "./dist/platform-genesis.d.ts",
158
+ "default": "./dist/platform-genesis.js"
159
+ },
156
160
  "./ubuntu": {
157
161
  "types": "./dist/ubuntu.d.ts",
158
162
  "default": "./dist/ubuntu.js"