/** * TypeScript authoring surface for ForgeZero deployment plans. * * This module only constructs inert data. The production Agent never imports a * repository's TypeScript definition; `fz deploy compile` turns it into the * canonical JSON plan consumed by the Agent. */ export type JsonPrimitive = string | number | boolean | null; export type JsonValue = JsonPrimitive | JsonValue[] | { [key: string]: JsonValue; }; export type JsonObject = { [key: string]: JsonValue; }; export type InputDefinition = { type: 'string'; required?: boolean; default?: string; minimumLength?: number; maximumLength?: number; pattern?: string; } | { type: 'integer'; required?: boolean; default?: number; minimum?: number; maximum?: number; } | { type: 'number'; required?: boolean; default?: number; minimum?: number; maximum?: number; } | { type: 'boolean'; required?: boolean; default?: boolean; } | { type: 'enum'; values: readonly string[]; required?: boolean; default?: string; } | { type: 'hostname'; required?: boolean; default?: string; }; export interface ValueReference { readonly $ref: `inputs.${string}` | `steps.${string}.status` | `steps.${string}.outputs.${string}` | `components.${string}.${string}` | `targets.${string}.${string}` | `deployment.${string}` | `execution.${string}`; } export type IntegerValue = number | ValueReference; export type StringValue = string | ValueReference; export interface ComputeConnectivityDefinition { private?: { mode: 'disabled' | 'private-lan'; } | { mode: 'cloudflare-warp'; credential: string; network: StringValue; }; public?: { mode: 'disabled'; } | { mode: 'cloudflare-tunnel'; credential: string; zone: StringValue; hostname: { mode: 'static'; label: StringValue; } | { mode: 'indexed'; prefix: StringValue; startAt?: number; }; }; } /** * A deployment may require one stable coordination role per physical site. * The control plane groups computes by their admitted Metal identity; users do * not name a particular machine as "master". A failed relay is replaced by * the declared standby and the assignment generation is fenced by the API. */ export interface ComputeTopologyDefinition { groupBy: 'metal'; relays: { activePerMetal: 1; standbyPerMetal: 0 | 1; /** Exact TCP endpoint used to prove the selected relay is actually serving. */ healthPort: number; /** Exact private TCP services routed and admitted between deployment sites. */ routedTcpPorts: readonly number[]; }; crossMetal: { mode: 'private-lan'; } | { mode: 'cloudflare-warp'; credential: string; network: StringValue; } | { mode: 'auto'; /** One or two directly reachable sites never install WARP. */ directPrivateMaximumMetals: 2; credential: string; network: StringValue; }; } export type ResolvableJsonValue = JsonPrimitive | ValueReference | readonly ResolvableJsonValue[] | { [key: string]: ResolvableJsonValue; }; export type ResolvableJsonObject = { [key: string]: ResolvableJsonValue; }; export type ConditionOperand = JsonPrimitive | ValueReference; export type Condition = { all: readonly Condition[]; } | { any: readonly Condition[]; } | { not: Condition; } | { equals: readonly [ConditionOperand, ConditionOperand]; } | { notEquals: readonly [ConditionOperand, ConditionOperand]; } | { greaterThan: readonly [ConditionOperand, ConditionOperand]; } | { greaterThanOrEqual: readonly [ConditionOperand, ConditionOperand]; } | { lessThan: readonly [ConditionOperand, ConditionOperand]; } | { lessThanOrEqual: readonly [ConditionOperand, ConditionOperand]; } | { contains: readonly [ConditionOperand, ConditionOperand]; } | { startsWith: readonly [ConditionOperand, ConditionOperand]; } | { exists: ValueReference; } | { succeeded: string; } | { failed: string; } | { changed: string; }; export declare const CREDENTIAL_PURPOSES: readonly ["deployment-infrastructure", "runtime-secret"]; export type CredentialPurpose = (typeof CREDENTIAL_PURPOSES)[number]; export interface CredentialDefinition { purpose: CredentialPurpose; /** Required by default. Optional declarations do not block a release while their binding is absent. */ required?: boolean; /** Omit only for a manual deployment value. The stored binding always records its resolved schema. */ schema?: string; source: { kind: 'vault'; name: string; }; } export interface TargetDefinition { kind: 'compute'; selector: { profiles: readonly string[]; operatingSystem: { id: 'ubuntu'; version: '24.04' | '26.04'; architecture: 'x64'; }; confidentialCompute?: 'required' | 'preferred' | 'disabled'; labels?: Readonly>; }; cardinality: { minimum: number; desired: number | ValueReference; maximum: number; }; /** * Capacity reserved for every stable target slot. This is placement intent, * not an application cgroup limit. The API first binds an eligible idle * compute with at least this unreserved capacity; provisioning is allowed * only when the separately approved control-plane policy permits it. */ allocation: { /** * Runtime selected for application components on this compute. This does * not prohibit reviewed host-native infrastructure components: an * exclusive OCI/runc target may also host a native database. */ execution: 'native' | 'oci-runc' | 'oci-kata-qemu-snp'; sharing: 'exclusive' | 'shared'; resources: { cpuCores: IntegerValue; memoryMiB: IntegerValue; storageGiB: IntegerValue; }; existing: 'prefer' | 'require'; }; /** Required only when the control plane may create capacity after reuse is exhausted. */ provisioning?: { regionKey: string; imageKey: string; environmentKey: string; ownership: 'platform' | 'tenant-metal'; metalHostname?: string; resources: { physicalCores: number; vcpu: number; memoryGib: number; diskGib: number; diskEncryption?: 'none' | 'luks2'; egressGuaranteedMbps: number; egressBurstMbps: number; confidential: boolean; }; monthlyAmountCents: string; maxMonthlySpendMinor: string; }; /** Per-slot connectivity intent. Credential names resolve through the scoped Vault, never to plan values. */ connectivity?: ComputeConnectivityDefinition; topology?: ComputeTopologyDefinition; placement?: { /** Physical-host relationship between stable slots of this target. */ metal?: 'any' | 'same' | 'different'; /** Strict refuses when the relationship cannot be met; allow-any relaxes it explicitly. */ fallback?: 'strict' | 'allow-any'; /** Compatibility authoring form; `metal` is the preferred explicit contract. */ spreadBy?: readonly ('metal' | 'region' | 'zone')[]; antiAffinity?: readonly string[]; }; } /** Compact TypeScript input normalized into the explicit wire shape above. */ export interface ComputePoolDefinition { profiles: readonly string[]; replicas: number | { minimum: number; desired: number | ValueReference; maximum: number; }; resources: { cpuCores: IntegerValue; memoryMiB: IntegerValue; storageGiB: IntegerValue; }; os?: 'ubuntu-24.04' | 'ubuntu-26.04'; runtime?: 'native' | 'oci-runc' | 'oci-kata-qemu-snp'; isolation?: 'standard' | 'sev-snp'; sharing?: 'exclusive' | 'shared'; reuse?: 'prefer' | 'require'; provisioning?: TargetDefinition['provisioning']; connectivity?: ComputeConnectivityDefinition; topology?: ComputeTopologyDefinition; labels?: Readonly>; placement?: TargetDefinition['placement']; } export interface RequirementDefinition { capability: string; provider: string; contract: number; version: string; config: TConfig; when?: Condition; } export interface ResourceDefinition { cpu?: { limit: number; weight?: number; pinning?: 'automatic' | 'dedicated'; }; memory?: { limitMiB: number; reservationMiB?: number; swap?: 'disabled' | 'bounded'; }; pids?: { limit: number; }; io?: { weight?: number; readBps?: number; writeBps?: number; readIops?: number; writeIops?: number; }; } export interface HealthDefinition { protocol: 'http'; method: 'GET' | 'HEAD'; path: string; expectedStatus: readonly number[]; timeoutMs: number; intervalMs?: number; attempts?: number; } /** * Durable state is explicit. ForgeZero never claims arbitrary process-memory * transfer: a workload is stateless, reopens a shared durable store, or owns a * versioned localhost handoff adapter whose payload remains runtime-to-runtime. */ export type DeploymentStateDefinition = { mode: 'stateless'; } | { mode: 'shared-durable'; } | { mode: 'runtime-handoff'; protocol: 'forgezero-state-handoff/v1'; schemaVersion: number; exportPath: string; beginPath: string; statusPath: string; timeoutMs: number; intervalMs?: number; }; export type DeploymentDrainDefinition = { mode: 'timeout'; timeoutMs: number; } | { mode: 'runtime'; protocol: 'forgezero-drain/v1'; beginPath: string; statusPath: string; timeoutMs: number; intervalMs?: number; }; export type StorageMount = { class: 'ephemeral'; path: string; type: 'tmpfs'; sizeMiB: number; } | { class: 'persistent'; name: string; path: string; minimumFreePercent?: number; } | { class: 'database'; name: string; path: string; minimumFreePercent: number; minimumIops?: number; latencyTargetMs?: number; }; export interface NetworkDefinition { ingress?: { exposure: 'loopback' | 'private' | 'public'; stablePort?: number; }; private?: { mode: 'private-lan' | 'cloudflare-warp' | 'auto'; preferences?: readonly ('private-lan' | 'cloudflare-warp')[]; }; public?: { mode: 'disabled' | 'cloudflare-tunnel'; optional?: boolean; }; container?: { mode: 'bridge' | 'host'; network?: string; }; } export type ApplicationRuntime = { kind: 'native'; provider: string; requirement: string; argv: readonly string[]; /** Optional root-owned host profile. The deployment may select it but cannot define its privileges. */ profile?: string; } | { kind: 'container'; provider: string; requirement: string; /** runc shares the compute kernel; Kata creates one measured QEMU SNP workload VM. */ runtimeClass?: 'runc' | 'kata-qemu-snp'; image: { source: { kind: 'build'; context: string; dockerfile: string; } | { kind: 'registry'; reference: string; }; }; entrypoint?: readonly string[]; security: { privileged: false; noNewPrivileges: true; root: 'read-only' | 'writable'; dropCapabilities: readonly string[]; }; }; export interface ApplicationComponent { kind: 'application'; target: string; runtime: ApplicationRuntime; service: { protocol: 'http'; port: number; health: HealthDefinition; websocket?: boolean; maximumConnections?: number; }; state: DeploymentStateDefinition; /** Optional bounded loopback workload calibration performed after a healthy release. */ capacityCalibration?: { path: string; maxConcurrency?: number; requestsPerWorker?: number; maximumRequestsPerWorker?: number; maxP95Ms?: number; maxErrorRate?: number; safetyRatio?: number; requestTimeoutMs?: number; minimumStageDurationMs?: number; maxCpuUtilizationPercent?: number; maxMemoryUtilizationPercent?: number; }; resources: ResourceDefinition; storage?: readonly StorageMount[]; network?: NetworkDefinition; rollout: { strategy: 'direct' | 'blue-green' | 'rolling' | 'canary'; proxy?: string; drain?: DeploymentDrainDefinition; automaticRollback?: boolean; }; } export interface DatabaseComponent { kind: 'database'; target: string; /** Runtime-secret Vault alias containing fz.database/arangodb@1. */ credential?: string; runtime: { provider: string; requirement: string; mode: 'native'; }; topology: { mode: 'standalone'; } | { mode: 'cluster'; bootstrapMembers: number; replicationFactor: number; writeConcern: number; additionalJoiners: 'allowed' | 'disabled'; }; resources?: ResourceDefinition; storage: StorageMount & { class: 'database'; }; network: NetworkDefinition; } export type ComponentDefinition = ApplicationComponent | DatabaseComponent; export type StepScope = { kind: 'release-executor'; } | { kind: 'elected-one'; group: string; } | { kind: 'each-target'; target: string; } | { kind: 'target-batches'; target: string; size: number; } | { kind: 'topology-role'; target: string; role: 'relay' | 'standby' | 'member'; }; export interface RetryDefinition { attempts: number; backoff: { kind: 'fixed' | 'linear' | 'exponential'; initialMs: number; maximumMs: number; }; retryOn?: readonly ('network' | 'timeout' | 'provider-unavailable' | 'rate-limited' | 'conflict')[]; } export interface WorkflowStepDefinition { uses: `${string}@${number}`; with: TWith; if?: Condition; scope: StepScope; timeoutMs?: number; retry?: RetryDefinition; failure?: { policy: 'continue' | 'stop' | 'rollback-stage' | 'rollback-deployment' | 'compensate' | 'manual-intervention'; }; compensate?: { uses: `${string}@${number}`; with: ResolvableJsonObject; }; } export interface StageDefinition { dependsOn?: readonly string[]; if?: Condition; strategy: { mode: 'sequential' | 'parallel' | 'rolling' | 'blue-green' | 'canary'; maximumConcurrency?: number; batchSize?: number; minimumHealthy?: number; increments?: readonly number[]; observationMs?: number; }; steps: Readonly>; } export interface WorkflowDefinition { concurrency?: { group: string; limit: number; }; stages: Readonly>; } export interface DeploymentSource { apiVersion: 'deploy.forgezero.net/v2'; kind: 'Deployment'; metadata: { name: string; description?: string; }; spec: { /** Exact Git branch this checked-in plan is valid for. */ source: { branch: string; }; security?: { attestation?: 'required' | 'preferred' | 'disabled'; }; inputs?: Readonly>; credentials?: Readonly>; targets: Readonly>; requirements?: Readonly>; components: Readonly>; workflows: Readonly>; }; } export declare const input: { string: (value?: Omit, "type">) => { readonly required?: boolean; readonly default?: string; readonly minimumLength?: number; readonly maximumLength?: number; readonly pattern?: string; readonly type: "string"; }; integer: (value?: Omit, "type">) => { readonly required?: boolean; readonly default?: number; readonly minimum?: number; readonly maximum?: number; readonly type: "integer"; }; number: (value?: Omit, "type">) => { readonly required?: boolean; readonly default?: number; readonly minimum?: number; readonly maximum?: number; readonly type: "number"; }; boolean: (value?: Omit, "type">) => { readonly required?: boolean; readonly default?: boolean; readonly type: "boolean"; }; enum: (value: { values: T; required?: boolean; default?: T[number]; }) => { readonly values: T; readonly required?: boolean; readonly default?: T[number]; readonly type: "enum"; }; hostname: (value?: Omit, "type">) => { readonly required?: boolean; readonly default?: string; readonly type: "hostname"; }; ref: (name: T) => ValueReference; }; export declare const ref: { stepStatus: (step: string) => ValueReference; stepOutput: (step: Step, output: Output) => { $ref: `steps.${Step}.outputs.${Output}`; }; component: (component: string, property: string) => ValueReference; target: (target: string, property: string) => ValueReference; deployment: (property: string) => ValueReference; /** Secret-free control-plane assignment of the compute executing this step. */ execution: (property: "targetName" | "slot" | "releaseExecutor" | "runtime" | "cpuCores" | "memoryMiB" | "storageGiB" | "site" | "topologyRole" | "topologyTransport" | "localRelayAddress") => ValueReference; }; export declare const conditions: { all: (...values: Condition[]) => Condition; any: (...values: Condition[]) => Condition; not: (value: Condition) => Condition; equals: (left: ConditionOperand, right: ConditionOperand) => Condition; notEquals: (left: ConditionOperand, right: ConditionOperand) => Condition; greaterThan: (left: ConditionOperand, right: ConditionOperand) => Condition; greaterThanOrEqual: (left: ConditionOperand, right: ConditionOperand) => Condition; lessThan: (left: ConditionOperand, right: ConditionOperand) => Condition; lessThanOrEqual: (left: ConditionOperand, right: ConditionOperand) => Condition; contains: (left: ConditionOperand, right: ConditionOperand) => Condition; startsWith: (left: ConditionOperand, right: ConditionOperand) => Condition; exists: (value: ValueReference) => Condition; succeeded: (step: string) => Condition; failed: (step: string) => Condition; changed: (step: string) => Condition; }; export declare const credential: { infrastructure: (value: { schema?: string; name: string; required?: boolean; }) => CredentialDefinition; runtime: (value: { schema?: string; name: string; required?: boolean; }) => CredentialDefinition; }; export declare const target: { compute: (value: ComputePoolDefinition | Omit) => TargetDefinition; }; export declare function requirement(value: RequirementDefinition): RequirementDefinition; export declare function application(value: Omit): ApplicationComponent; export declare function database(value: Omit): DatabaseComponent; export declare function step(value: WorkflowStepDefinition): WorkflowStepDefinition; export declare function stage(value: StageDefinition): StageDefinition; export declare function workflow(value: WorkflowDefinition): WorkflowDefinition; export declare function defineDeployment(definition: T): T; export { actions } from './deploy-actions'; export { providers } from './deploy-providers'; export type { ArangoDbProviderConfig, BunProviderConfig, CloudflaredProviderConfig, ContainerdProviderConfig, DockerProviderConfig, KataProviderConfig, NginxProviderConfig, OpenSshProviderConfig, SystemdProviderConfig, UfwProviderConfig, WarpProviderConfig } from './deploy-providers';