@forgezero/agent 0.1.10 → 0.1.11

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/fz-agent.js CHANGED
@@ -1382,7 +1382,15 @@ async function pullProvisioningOnce(options) {
1382
1382
  if (options.metalPreflight) {
1383
1383
  const report = options.metalPreflight();
1384
1384
  const accepted = await postSignedNode(options, "v1/metal/preflight", report);
1385
- options.onEvent?.("preflight", { ...report, ready: accepted.ready, state: accepted.state });
1385
+ if (options.metalHostname && accepted.hostname !== options.metalHostname) {
1386
+ throw new Error(`metal agent: configured inventory hostname ${options.metalHostname} is bound as ${accepted.hostname}; refusing work.`);
1387
+ }
1388
+ options.onEvent?.("preflight", {
1389
+ ...report,
1390
+ hostname: accepted.hostname,
1391
+ ready: accepted.ready,
1392
+ state: accepted.state
1393
+ });
1386
1394
  if (!accepted.ready)
1387
1395
  return { status: "idle" };
1388
1396
  }
@@ -2662,7 +2670,7 @@ async function applyMetalIsolation(profile, exec = defaultExec) {
2662
2670
  }
2663
2671
 
2664
2672
  // src/index.ts
2665
- var VERSION = "0.1.10";
2673
+ var VERSION = "0.1.11";
2666
2674
  function loadOrCreateSeed(path) {
2667
2675
  if (existsSync9(path)) {
2668
2676
  const seed2 = new Uint8Array(Buffer.from(readFileSync5(path, "utf8").trim(), "base64url"));
@@ -2860,6 +2868,8 @@ if (import.meta.main) {
2860
2868
  if (process.env.FZ_AGENT_ROLE === "metal") {
2861
2869
  if (!process.env.FZ_API)
2862
2870
  throw new Error("metal agent requires FZ_API");
2871
+ if (!process.env.FZ_METAL_HOSTNAME)
2872
+ throw new Error("metal agent requires FZ_METAL_HOSTNAME");
2863
2873
  const seed = process.env.FZ_SEED_CREDENTIAL ? loadSeedCredential(process.env.FZ_SEED_CREDENTIAL) : loadOrCreateSeed(process.env.FZ_SEED_PATH ?? DEFAULT_SEED_PATH);
2864
2874
  const keys2 = deriveKeysFromSeed(seed);
2865
2875
  const nodeKey2 = process.env.FZ_NODE_KEY ?? keys2.ed25519.publicKey;
@@ -2867,6 +2877,7 @@ if (import.meta.main) {
2867
2877
  apiUrl: process.env.FZ_API,
2868
2878
  nodeKey: nodeKey2,
2869
2879
  keys: keys2,
2880
+ metalHostname: process.env.FZ_METAL_HOSTNAME,
2870
2881
  run: (claim) => requestMetalProvision(claim, process.env.FZ_METAL_HELPER_SOCKET ?? DEFAULT_METAL_HELPER_SOCKET),
2871
2882
  metalPreflight: () => ({
2872
2883
  snpHost: existsSync9("/dev/sev"),
package/dist/index.d.ts CHANGED
@@ -25,7 +25,7 @@ import type { SecretCache } from './cache';
25
25
  * That preference was implemented in the client long before anything listened.
26
26
  * See `socket.ts` for why it signs rather than handing back a token.
27
27
  */
28
- export declare const VERSION = "0.1.10";
28
+ export declare const VERSION = "0.1.11";
29
29
  export { startAgent, handleRequest } from './socket';
30
30
  export type { AgentOptions, AttestationSource, Request, Response } from './socket';
31
31
  export { createSecretCache, CacheError } from './cache';
@@ -36,6 +36,8 @@ export type ProvisionRunner = (claim: RemoteProvisionClaim) => Promise<Provision
36
36
  export interface ProvisioningPullOptions extends SignedNodeHttpOptions {
37
37
  keys: NodeKeyPair;
38
38
  run: ProvisionRunner;
39
+ /** Inventory record this physical host was deliberately configured to serve. */
40
+ metalHostname?: string;
39
41
  intervalMs?: number;
40
42
  completionAttempts?: number;
41
43
  sleep?: (ms: number) => Promise<void>;
@@ -123,7 +123,15 @@ async function pullProvisioningOnce(options) {
123
123
  if (options.metalPreflight) {
124
124
  const report = options.metalPreflight();
125
125
  const accepted = await postSignedNode(options, "v1/metal/preflight", report);
126
- options.onEvent?.("preflight", { ...report, ready: accepted.ready, state: accepted.state });
126
+ if (options.metalHostname && accepted.hostname !== options.metalHostname) {
127
+ throw new Error(`metal agent: configured inventory hostname ${options.metalHostname} is bound as ${accepted.hostname}; refusing work.`);
128
+ }
129
+ options.onEvent?.("preflight", {
130
+ ...report,
131
+ hostname: accepted.hostname,
132
+ ready: accepted.ready,
133
+ state: accepted.state
134
+ });
127
135
  if (!accepted.ready)
128
136
  return { status: "idle" };
129
137
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "//": "Publishing happens from an operator's machine, not CI \u2014 CLAUDE.md records that the absence of CI is deliberate. npm's `provenance` attests a tarball was built by a recognised CI provider from a named commit, so it cannot be produced here: it was set, and the first publish failed with `Automatic provenance generation not supported for provider: null`. A setting that can never be satisfied is worse than none, because it reads as a guarantee nobody is getting. Restore it the day this publishes from CI, and not before.",
3
3
  "name": "@forgezero/agent",
4
- "version": "0.1.10",
4
+ "version": "0.1.11",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "check": "tsc --noEmit",