import type { AppEnvironmentId } from '../environments'; import type { InfraAdapterId } from './infraManifest'; import type { InfraSecretReference } from './infraSecrets'; import type { InfraComputeTarget } from './infraTargets'; /** Identity must be verified before mutation; unowned resources must never be pruned. */ export interface InfraResourceIdentity { readonly projectId: string; readonly environment: AppEnvironmentId; readonly adapter: InfraAdapterId; readonly resourceId: string; } export interface InfraOwnedResource { readonly identity: InfraResourceIdentity; readonly externalId?: string; readonly persistent: boolean; readonly retention: 'retain' | 'delete-on-destroy'; readonly dependsOn: readonly InfraResourceIdentity[]; } export interface InfraDiagnostic { readonly severity: 'info' | 'warning' | 'error'; readonly code: string; /** Safe human-readable detail. Tokens and privileged values must be redacted by the producer. */ readonly message: string; readonly path?: readonly (string | number)[]; readonly owner?: InfraResourceIdentity; } export type InfraResult = | { readonly ok: true; readonly value: T; readonly diagnostics: readonly InfraDiagnostic[] } | { readonly ok: false; readonly diagnostics: readonly InfraDiagnostic[] }; export interface InfraPlanAction { readonly owner: InfraResourceIdentity; readonly operation: 'create' | 'update' | 'delete' | 'retain' | 'noop'; readonly impact: 'none' | 'interrupts-service' | 'deletes-data'; readonly detail: string; readonly dependsOn: readonly InfraResourceIdentity[]; } export interface InfraPlan { readonly projectId: string; readonly environment: AppEnvironmentId; /** Ordered dependency-first; teardown consumers reverse dependency order. */ readonly actions: readonly InfraPlanAction[]; } export interface InfraResourceStatus { readonly owner: InfraResourceIdentity; readonly state: 'absent' | 'pending' | 'ready' | 'degraded' | 'stopped' | 'retained' | 'failed' | 'unknown'; readonly detail?: string; readonly diagnostics?: readonly InfraDiagnostic[]; } export interface InfraStatus { readonly projectId: string; readonly environment: AppEnvironmentId; readonly state: InfraResourceStatus['state']; readonly resources: readonly InfraResourceStatus[]; } /** A privileged output has a reference, never a value field or environment export name. */ export type InfraOutput = { readonly owner: InfraResourceIdentity; readonly name: string } & ( | { readonly visibility: 'public'; readonly value: string | number | boolean; readonly environmentVariable?: string; readonly reference?: never; } | { readonly visibility: 'secret'; readonly reference: InfraSecretReference; readonly value?: never; readonly environmentVariable?: never; } ); export interface InfraGeneratedArtifact { readonly owner: InfraResourceIdentity; /** Project-relative file path validated by the writer before touching the filesystem. */ readonly path: string; readonly content: string; readonly executable?: boolean; } export interface InfraLedger { readonly schemaVersion: 1; readonly projectId: string; readonly environment: AppEnvironmentId; /** Last successfully reconciled portable targets required by stateless runtime operations. */ readonly targets: readonly InfraComputeTarget[]; readonly resources: readonly InfraOwnedResource[]; /** Last successfully reconciled public values and privileged references; never resolved secrets. */ readonly outputs: readonly InfraOutput[]; readonly artifacts: readonly { readonly owner: InfraResourceIdentity; readonly path: string }[]; } /** No default environment or confirmation is possible for destruction. */ export interface InfraDestroyRequest { readonly projectId: string; readonly environment: AppEnvironmentId; readonly confirmation: { readonly projectId: string; readonly environment: AppEnvironmentId }; /** Data deletion is a separate, explicit resource-scoped authorization in every environment. */ readonly persistence: | { readonly policy: 'retain' } | { readonly policy: 'delete'; readonly confirmedResources: readonly InfraResourceIdentity[] }; }