@alneas/eaos-server 0.1.0 → 0.2.0
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/CHANGELOG.md +20 -0
- package/README.ja.md +28 -18
- package/README.md +8 -2
- package/dist/agentic/agent-jobs.d.ts +5 -1
- package/dist/agentic/autonomous-worker.d.ts +30 -3
- package/dist/agentic/autonomous-worker.js +2 -1
- package/dist/agentic/event-bridge.d.ts +6 -0
- package/dist/agentic/index.d.ts +7 -3
- package/dist/agentic/index.js +2 -1
- package/dist/agentic/local-runner.d.ts +6 -2
- package/dist/chunk-4BARRLJR.js +180 -0
- package/dist/chunk-4BARRLJR.js.map +1 -0
- package/dist/{chunk-THYUY5ZZ.js → chunk-F2J6IQ6I.js} +68 -25
- package/dist/chunk-F2J6IQ6I.js.map +1 -0
- package/dist/{chunk-6KV5CJBW.js → chunk-F4IITPGX.js} +5 -5
- package/dist/{chunk-DHQGNP4T.js → chunk-SDJNYPYK.js} +2 -2
- package/dist/{chunk-DHQGNP4T.js.map → chunk-SDJNYPYK.js.map} +1 -1
- package/dist/chunk-YMHVRBUU.js +199 -0
- package/dist/chunk-YMHVRBUU.js.map +1 -0
- package/dist/db-package/index.js +3 -3
- package/dist/engine.js +2 -2
- package/dist/execution/chat.d.ts +7 -0
- package/dist/execution/chat.js +7 -0
- package/dist/execution/chat.js.map +1 -0
- package/dist/execution/index.d.ts +294 -2
- package/dist/execution/index.js +10 -1
- package/dist/execution/index.js.map +1 -1
- package/dist/execution/tool-agent.d.ts +7 -0
- package/dist/execution/tool-agent.js +8 -0
- package/dist/execution/tool-agent.js.map +1 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.js +4 -3
- package/dist/lifecycle-engine/backend-migration.js +1 -1
- package/dist/lifecycle-engine/baseline.js +1 -1
- package/dist/lifecycle-engine/index.js +1 -1
- package/dist/lifecycle-engine/platform/index.js +8 -8
- package/dist/sql-lifecycle/index.d.ts +1 -1
- package/docs/api.md +809 -2
- package/docs/guide.md +44 -0
- package/docs/index.md +6 -2
- package/package.json +12 -3
- package/dist/chunk-THYUY5ZZ.js.map +0 -1
- /package/dist/{chunk-6KV5CJBW.js.map → chunk-F4IITPGX.js.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lifecycle-engine/baseline.ts","../src/lifecycle-engine/index.ts","../package.json","../src/lifecycle-engine/backend-migration.ts"],"sourcesContent":["import { lt, valid, satisfies } from 'semver'\nimport { lifecycleDigest, resolveDataContracts, type DataContract, type LifecycleStore, type MigrationRecord } from './index'\n\n/**\n * Hash-bound replacement of exact historical database migrations by equivalent baseline DDL.\n * \n * @see createDataContractBaseline for canonical integration usage.\n */\nexport interface DataContractBaseline {\n /**\n * Baseline discriminator; currently 1.\n */\n format: 1\n /**\n * Canonical contract release whose fully applied history is replaced.\n */\n source: DataContract\n /**\n * Newer release retaining schema but using one database-scoped baseline migration.\n */\n target: DataContract\n /**\n * Ordered historical migration IDs, positions and checksums requiring exact ledger matches.\n */\n replaces: { \n /**\n * Original immutable migration ID replaced by the baseline.\n */\n id: string; \n /**\n * Original zero-based migration position.\n */\n position: number; \n /**\n * Canonical original migration definition digest.\n */\n checksum: string }[]\n /**\n * Canonical digest of format/source/target/replaces.\n */\n hash: string\n}\n/**\n * Builds a newer single-migration contract release and hashes the exact historical migrations it replaces.\n * \n * Final DDL comes from a schema compiler or an isolated database introspector, never concatenation.\n * @param source - Valid source contract with nonempty database-scoped migration history.\n * @param version - Valid semver strictly newer than source.version.\n * @param sql - Compiler/introspector-generated complete baseline DDL covering exactly the original dialect set.\n * @returns Source/target contract snapshots, replacement migration checksums and integrity hash.\n * @throws Error for nonnewer version, tenant-scoped/empty history, changed dialect set or invalid source/target contracts.\n * \n * @remarks\n * Read-only; the host must establish final DDL equivalence using a schema compiler or isolated introspector. SQL is not concatenated or executed here.\n * \n * @example\n * ```typescript\n * import { createDataContractBaseline, type DataContract } from '@alneas/eaos-server/lifecycle-engine';\n * export function reviewBaseline(source: DataContract, version: string, sql: DataContract['migrations'][number]['sql']) { return createDataContractBaseline(source, version, sql); }\n * ```\n */\nexport function createDataContractBaseline(source: DataContract, version: string, sql: DataContract['migrations'][number]['sql']): DataContractBaseline {\n if (!valid(version) || !lt(source.version, version) || !source.migrations.length || source.migrations.some(m => m.scope !== 'database')) throw Error('Baseline requires a newer contract version and database-scoped migrations')\n const dialects = [...new Set(source.migrations.flatMap(m => Object.keys(m.sql)))].sort()\n if (JSON.stringify(dialects) !== JSON.stringify(Object.keys(sql).sort())) throw Error('Baseline must preserve every declared dialect')\n const target: DataContract = { ...structuredClone(source), version, migrations: [{ id: `001_baseline_v${version.replaceAll('.', '_').replaceAll('-', '_')}`, scope: 'database', sql: structuredClone(sql) }] }\n resolveDataContracts([{ ...source, dependencies: undefined }], { [source.id]: source.version })\n resolveDataContracts([{ ...target, dependencies: undefined }], { [target.id]: version })\n const body = { format: 1 as const, source: structuredClone(source), target, replaces: source.migrations.map((m, position) => ({ id: m.id, position, checksum: lifecycleDigest(m) })) }\n return { ...body, hash: lifecycleDigest(body) }\n}\n/**\n * Replaces a completely applied exact contract history with its reviewed baseline ledger record without running DDL.\n * \n * Rebase only a completely applied exact history. This function never executes DDL.\n * @param store - Durable cross-process exclusive lifecycle store.\n * @param databaseId - Physical database ledger identity whose contract history is rebased.\n * @param baseline - Unmodified baseline created by createDataContractBaseline.\n * @param options - Expected ledger revision and optional all-instance quiesce callback, required when affected consumers are active.\n * @returns Baseline hash, next revision, count of replaced records and ddlExecuted=false.\n * @throws Rejects integrity mismatch, stale revision, partial/dirty history, incompatible installed consumer range, absent drain or propagated store/quiesce failures.\n * \n * @remarks\n * Runs under the store lock, archives old migration history and disables affected live consumers. Host drain happens before the final atomic state write; external drain may have occurred even if that write fails. No schema or data migration is executed.\n * \n * @example\n * ```typescript\n * import { rebaseDataContractBaseline, type DataContractBaseline, type LifecycleStore } from '@alneas/eaos-server/lifecycle-engine';\n * export function rebaseReviewed(store: LifecycleStore, databaseId: string, baseline: DataContractBaseline, options: Parameters<typeof rebaseDataContractBaseline>[3]) { return rebaseDataContractBaseline(store, databaseId, baseline, options); }\n * ```\n */\nexport async function rebaseDataContractBaseline(store: LifecycleStore, databaseId: string, baseline: DataContractBaseline, options: {\n \n /**\n * Exact current ledger revision reviewed by the caller; mismatch rejects before mutation.\n */\n expectedRevision: number\n /** Host drains all instances before disabling the affected live consumers. */\n quiesce?: (input: { \n /**\n * Exact physical database identity whose live consumers must drain.\n */\n databaseId: string; \n /**\n * Distinct affected feature IDs consuming the rebased contract.\n */\n pluginIds: string[] }) => Promise<void>\n}) {\n const { hash, ...body } = baseline\n if (hash !== lifecycleDigest(body) || hash !== createDataContractBaseline(baseline.source, baseline.target.version, baseline.target.migrations[0]?.sql ?? {}).hash) throw Error('Baseline integrity differs')\n return store.withLock(async writer => {\n const state = await writer.read()\n if (state.revision !== options.expectedRevision) throw Error('Baseline plan is stale')\n const key = JSON.stringify([databaseId, baseline.source.id]), installed = state.dataContracts?.[key]\n if (!installed || installed.status !== 'installed' || installed.digest !== lifecycleDigest(baseline.source)) throw Error('Baseline source contract is not completely installed')\n const identity = baseline.source.migrationIdentity ?? `data-${baseline.source.id}`\n const history = Object.entries(state.migrations).filter(([, r]) => r.databaseId === databaseId && r.pluginId === identity)\n if (history.length !== baseline.replaces.length || baseline.replaces.some(replaced => !history.some(([, r]) => r.migrationId === replaced.id && r.position === replaced.position && r.checksum === replaced.checksum && r.tenantId === null && r.status === 'applied'))) throw Error('Baseline history is partial, changed or dirty')\n for (const [key, installed] of Object.entries(state.installations)) {\n const range = installed.release.schemaDependencies?.[baseline.source.id]\n if (state.backends[JSON.parse(key)[0]]?.databaseId === databaseId && range && !satisfies(baseline.target.version, range)) throw Error('Baseline violates an installed plugin contract range')\n }\n const live = Object.values(state.activations).filter(a => a.enabled && state.backends[a.backendId]?.databaseId === databaseId && state.installations[JSON.stringify([a.backendId, a.pluginId])]?.release.schemaDependencies?.[baseline.source.id])\n if (live.length && !options.quiesce) throw Error('Baseline requires all-instance drain')\n if (live.length) await options.quiesce!({ databaseId, pluginIds: [...new Set(live.map(a => a.pluginId))] })\n for (const a of live) a.enabled = false\n state.baselineHistory ??= {}\n const archiveKey = JSON.stringify([databaseId, identity, hash])\n if (state.baselineHistory[archiveKey]) throw Error('Baseline history already exists')\n state.baselineHistory[archiveKey] = { hash, source: baseline.source, migrations: Object.fromEntries(history) }\n for (const [key] of history) delete state.migrations[key]\n const m = baseline.target.migrations[0]\n state.migrations[JSON.stringify([databaseId, identity, m.id, '*'])] = { databaseId, pluginId: identity, migrationId: m.id, position: 0, tenantId: null, checksum: lifecycleDigest(m), status: 'applied' }\n state.dataContracts![key] = { contract: structuredClone(baseline.target), digest: lifecycleDigest(baseline.target), status: 'installed' }\n state.revision++\n await writer.write(state)\n return { baselineHash: hash, revision: state.revision, rebased: history.length, ddlExecuted: false as const }\n })\n}\n","import { dataContractTables, resolveDataContracts, type DataContract, type DataContractCatalog } from '@alneas/eaos-core/contracts/data-contracts'\nimport { createHash } from 'node:crypto'\nimport { satisfies, valid, validRange, lt } from 'semver'\nimport { version as packageVersion } from '../../package.json'\nimport type { BackendMigrationCutover, BackendMigrationPlan, BackendMigrationVerificationReport } from './backend-migration'\n/**\n * Installed server package version used as the default lifecycle compatibility version.\n * \n * @see PluginLifecycle for canonical integration usage.\n */\nexport const FRAMEWORK_VERSION = packageVersion\n/**\n * Supported SQL dialects used to select reviewed migration statements.\n * \n * @see PluginLifecycle for canonical integration usage.\n */\nexport type Dialect = 'sqlite' | 'oracle' | 'postgres'\nexport * from './baseline'\n/**\n * Opaque physical database placement and shared/dedicated tenant scope.\n * \n * @see PluginLifecycle for canonical integration usage.\n */\nexport interface BackendTarget {\n /**\n * Stable execution backend ID; lifecycle plans reject identity changes under an existing ID.\n */\n id: string;\n /**\n * Opaque physical database identity shared by aliases of the same database; never a DSN.\n */\n databaseId: string;\n /**\n * SQL dialect required by this database and migration history.\n */\n dialect: Dialect;\n /**\n * Shared permits tenant isolation within one database; dedicated binds one tenant.\n */\n mode: 'shared' | 'dedicated';\n /**\n * Required concrete tenant for dedicated mode and forbidden for shared mode.\n */\n tenantId?: string }\n/**\n * Immutable reviewed migration statements scoped to a physical database or one tenant.\n * \n * @see PluginLifecycle for canonical integration usage.\n */\nexport interface PluginMigration {\n /**\n * Stable unique migration ID whose applied definition must never be rewritten.\n */\n id: string;\n /**\n * Database runs once per physical database; tenant runs once per tenant.\n */\n scope: 'database' | 'tenant';\n /**\n * Dialect-to-ordered-statements map; the target dialect must have nonempty statements.\n */\n sql: Partial<Record<Dialect, string[]>> }\n/**\n * Trusted release definition with feature dependencies, schema requirements and immutable migrations.\n * \n * @see PluginLifecycle for canonical integration usage.\n */\nexport interface LifecyclePlugin {\n /**\n * Registered feature identifier, up to 128 letters/digits/underscore/hyphen characters starting alphanumeric.\n */\n id: string;\n /**\n * Valid semantic release version; changed contents require a version bump.\n */\n version: string;\n /**\n * Valid semver range for compatible framework versions.\n */\n framework: string\n /**\n * Optional feature ID to semver range dependencies installed/enabled as a closure.\n */\n dependencies?: Record<string, string>\n /**\n * Optional canonical data contract ranges; never installs or enables feature plugins.\n * \n * Storage dependencies do not install or enable a feature plugin.\n */\n schemaDependencies?: Record<string, string>\n /**\n * Optional canonical releases supplied by a data package; duplicate IDs must agree exactly.\n * \n * Canonical contract releases supplied by the data package, not inline table copies.\n */\n schemaContracts?: DataContract[]\n /**\n * Append-only reviewed plugin migrations; contract-backed plugins must put DDL in data contracts instead.\n * \n * Immutable, reviewed migrations generated from the plugin's schema; never rewrite applied IDs.\n */\n migrations: PluginMigration[]\n /**\n * Optional nonsecret declarative host requirements; absence causes no infrastructure work.\n * \n * Declarative, host-defined resource requirements. No secrets. Absence means no infrastructure changes.\n */\n infrastructure?: Record<string, unknown>\n}\n/**\n * Lifecycle change to installation or tenant activation; disable/uninstall retain business data.\n * \n * @see PluginLifecycle for canonical integration usage.\n */\nexport type Operation = 'install' | 'update' | 'enable' | 'disable' | 'uninstall'\n/**\n * Concrete lifecycle operation scoped to one registered backend and verified tenant.\n * \n * @see PluginLifecycle for canonical integration usage.\n */\nexport interface LifecycleRequest {\n /**\n * Requested install/update/enable/disable/uninstall transition.\n */\n operation: Operation;\n /**\n * Registered plugin ID, or bundle ID for bundle planning.\n */\n pluginId: string;\n /**\n * Registered execution backend ID.\n */\n backendId: string;\n /**\n * Verified concrete tenant; must match dedicated backend scope.\n */\n tenantId: string }\n/**\n * Durable per-database/tenant migration progress and immutable definition checksum.\n * \n * @see PluginLifecycle for canonical integration usage.\n */\nexport interface MigrationRecord {\n /**\n * Physical database on which the migration executes.\n */\n databaseId: string;\n /**\n * Plugin or canonical data-contract migration identity.\n */\n pluginId: string;\n /**\n * Immutable migration definition ID.\n */\n migrationId: string;\n /**\n * Zero-based position in the append-only migration history.\n */\n position: number;\n /**\n * Concrete tenant for tenant-scoped work, or null for database scope.\n */\n tenantId: string | null;\n /**\n * Canonical definition digest used to detect rewritten applied SQL.\n */\n checksum: string;\n /**\n * Running/applied/failed progress; running and failed require reconciliation before planning further changes.\n */\n status: 'running' | 'applied' | 'failed' }\n/**\n * Registered release snapshot and progress stored for one backend/plugin.\n * \n * @see PluginLifecycle for canonical integration usage.\n */\nexport interface Installation {\n /**\n * Copied trusted plugin release installed on this backend.\n */\n release: LifecyclePlugin;\n /**\n * Canonical digest of the release snapshot.\n */\n digest: string;\n /**\n * Installing/installed/failed progress; noninstalled records require reconciliation.\n */\n status: 'installing' | 'installed' | 'failed' }\n/**\n * Durable platform tenant metadata independent of business schemas.\n * \n * @see PluginLifecycle for canonical integration usage.\n */\nexport interface LifecyclePlatformTenant {\n /**\n * Stable concrete tenant ID.\n */\n id: string;\n /**\n * Public tenant display name.\n */\n name: string;\n /**\n * Whether platform tenant admission is enabled; membership remains host-owned.\n */\n active: boolean;\n /**\n * Configured tenant lookup domains; domain mapping alone never proves membership.\n */\n domains: readonly string[];\n /**\n * Tenant creation timestamp.\n */\n createdAt: string;\n /**\n * Latest metadata update timestamp.\n */\n updatedAt: string }\n/**\n * Durable tenant-to-backend routing assignment with optimistic routing revision.\n * \n * @see PluginLifecycle for canonical integration usage.\n */\nexport interface LifecyclePlatformPlacement {\n /**\n * Verified tenant whose traffic is routed.\n */\n tenantId: string;\n /**\n * Opaque configured backend receiving traffic.\n */\n backendId: string;\n /**\n * Nonnegative revision used to track routing changes.\n */\n routingRevision: number;\n /**\n * Timestamp of the recorded routing switch.\n */\n changedAt: string }\n/**\n * Nonsecret descriptive metadata for an existing backend.\n * \n * @see PluginLifecycle for canonical integration usage.\n */\nexport interface LifecyclePlatformBackendMetadata {\n /**\n * Optional public display label.\n */\n label?: string;\n /**\n * Optional provider descriptor; never credentials or DSNs.\n */\n provider?: string;\n /**\n * Optional declared host capability names, not permission grants.\n */\n capabilities?: readonly string[] }\n/**\n * Persisted migration progress including uncertainty, failure, reconciliation and rollback states.\n * \n * @see PluginLifecycle for canonical integration usage.\n */\nexport type LifecyclePlatformMigrationStatus = 'planned' | 'running' | 'verified' | 'cutover' | 'failed' | 'reconciling' | 'rolled-back'\n/**\n * Durable migration execution, verification and reconciliation evidence.\n * \n * @see PluginLifecycle for canonical integration usage.\n */\nexport interface LifecyclePlatformMigrationRecord {\n /**\n * Current progress; reconciling represents uncertain execution outcomes.\n */\n status: LifecyclePlatformMigrationStatus\n /**\n * Optional identity claiming the host migration execution.\n */\n executionId?: string\n /**\n * Optional host-reported verification matching the migration plan.\n */\n verification?: BackendMigrationVerificationReport\n /**\n * Optional source-retaining cutover receipt.\n */\n cutover?: BackendMigrationCutover\n /**\n * Optional failure message and occurrence timestamp; exclude secrets.\n */\n error?: { \n /**\n * Nonsecret failure description retained for operator reconciliation.\n */\n message: string; \n /**\n * Timestamp at which the error was recorded.\n */\n occurredAt: string }\n /**\n * Timestamp of the latest migration-state change.\n */\n updatedAt: string\n /**\n * Optional original migration ID when this is a rollback execution.\n */\n rollbackOf?: string\n /**\n * Optional reviewed reverse plan associated with this migration.\n */\n rollbackPlanId?: string\n}\n/**\n * Platform-owned tenant, backend and migration control maps stored with the lifecycle ledger.\n * \n * @see PluginLifecycle for canonical integration usage.\n */\nexport interface LifecyclePlatformState {\n /**\n * Tenant records indexed by tenant ID.\n */\n tenants: Record<string, LifecyclePlatformTenant>\n /**\n * Current routing assignments indexed by tenant ID.\n */\n placements: Record<string, LifecyclePlatformPlacement>\n /**\n * Nonsecret backend labels/provider capabilities indexed by backend ID.\n */\n backendMetadata: Record<string, LifecyclePlatformBackendMetadata>\n /**\n * Reviewed backend migration plans indexed by migration ID.\n */\n migrationPlans: Record<string, BackendMigrationPlan>\n /**\n * Execution/reconciliation records indexed by migration ID.\n */\n migrationRecords: Record<string, LifecyclePlatformMigrationRecord>\n}\n/**\n * Versioned durable control ledger for plugin readiness, schema history and platform placement.\n * \n * @see PluginLifecycle for canonical integration usage.\n */\nexport interface LifecycleState {\n /**\n * Optional archived exact histories replaced by reviewed baselines.\n */\n baselineHistory?: Record<string, { \n /**\n * Exact archived baseline integrity hash.\n */\n hash: string; \n /**\n * Original canonical contract release retained for historical evidence.\n */\n source: DataContract; \n /**\n * Archived exact applied migration receipts.\n */\n migrations: Record<string, MigrationRecord> }>\n /**\n * Persistent ledger discriminator; currently 1.\n */\n format: 1;\n /**\n * Nonnegative safe integer incremented on persisted lifecycle changes.\n */\n revision: number\n /**\n * Opaque backend target definitions indexed by backend ID.\n */\n backends: Record<string, BackendTarget>\n /**\n * Release snapshots indexed by JSON [backendId, pluginId].\n */\n installations: Record<string, Installation>\n /**\n * Requested tenant activation records indexed by JSON [backendId, tenantId, pluginId]; effective readiness is checked separately.\n */\n activations: Record<string, { \n /**\n * Registered execution backend owning this activation.\n */\n backendId: string; \n /**\n * Concrete verified tenant owning this activation.\n */\n tenantId: string; \n /**\n * Registered feature ID requested for activation.\n */\n pluginId: string; \n /**\n * Canonical release or infrastructure definition digest.\n */\n digest: string; \n /**\n * Requested activation flag; effective readiness also requires matching installed digests and dependencies.\n */\n enabled: boolean }>\n /**\n * Progress indexed by JSON [databaseId, migrationIdentity, migrationId, tenantId-or-*].\n */\n migrations: Record<string, MigrationRecord>\n /**\n * Infrastructure digests/progress indexed by JSON [backendId, pluginId].\n */\n infrastructure: Record<string, { \n /**\n * Canonical release or infrastructure definition digest.\n */\n digest: string; \n /**\n * Persisted installing/installed/failed or running/applied/failed progress, according to this ledger map.\n */\n status: 'running' | 'applied' | 'failed' }>\n /**\n * Tenant/control-plane metadata and backend migration evidence.\n */\n platform: LifecyclePlatformState\n /**\n * Optional canonical contract installation records indexed by JSON [databaseId, contractId].\n */\n dataContracts?: Record<string, { \n /**\n * Canonical schema contract release bound by its stored digest.\n */\n contract: DataContract; \n /**\n * Canonical release or infrastructure definition digest.\n */\n digest: string; \n /**\n * Persisted installing/installed/failed or running/applied/failed progress, according to this ledger map.\n */\n status: 'installing' | 'installed' | 'failed' }>\n}\n/**\n * Atomic lifecycle snapshot access made available inside the host's exclusive lock.\n * \n * @see PluginLifecycle for canonical integration usage.\n */\nexport interface LifecycleWriter {\n /**\n * Read the currently committed ledger snapshot; must not expose uncommitted writes.\n * @returns The currently committed atomic ledger snapshot.\n * @throws Host adapter or callback failures reject the returned Promise; side effects may already be partially complete.\n \n * @example\n * ```typescript\n * import type { LifecycleStore } from '@alneas/eaos-server/lifecycle-engine';\n * export async function readLocked(store: LifecycleStore) {\n * return store.withLock(async writer => writer.read());\n * }\n * ```\n */\n read(): Promise<LifecycleState>;\n /**\n * Atomically persist the complete next snapshot; resolve only after durable completion.\n * @param state - Complete next ledger snapshot with updated revision and control metadata.\n * @returns Resolves without a value after the complete snapshot is durably committed.\n * @throws Host adapter or callback failures reject the returned Promise; side effects may already be partially complete.\n \n * @example\n * ```typescript\n * import type { LifecycleStore } from '@alneas/eaos-server/lifecycle-engine';\n * export async function persistReviewedRevision(store: LifecycleStore) {\n * await store.withLock(async writer => {\n * const state = await writer.read();\n * // Domain changes belong in the same reviewed writer callback.\n * state.revision += 1;\n * await writer.write(state);\n * });\n * }\n * ```\n */\n write(state: LifecycleState): Promise<void> }\n/**\n * Durable lifecycle reads and cross-process exclusive writer coordination.\n * \n * \n * withLock must exclude every other writer, across processes. Reads must observe atomic committed snapshots.\n * @see PluginLifecycle for canonical integration usage.\n */\nexport interface LifecycleStore extends Pick<LifecycleWriter, 'read'> {\n /**\n * Exclude every competing writer across processes and hold the lock until the async callback settles; release on success or failure.\n * @param fn - Async work invoked only while holding exclusive writer ownership; receives atomic read/write capabilities.\n * @typeParam T - Result resolved by the exclusive-lock callback.\n * @returns The callback result after its lock is released; the lock is also released on failure.\n * @throws Host adapter or callback failures reject the returned Promise; side effects may already be partially complete.\n \n * @example\n * ```typescript\n * import type { LifecycleStore } from '@alneas/eaos-server/lifecycle-engine';\n * export async function snapshot(store: LifecycleStore) {\n * return store.withLock(async writer => writer.read());\n * }\n * ```\n */\n withLock<T>(fn: (writer: LifecycleWriter) => Promise<T>): Promise<T> }\n/**\n * Planned migration ledger identity and ordered SQL to execute on one physical target.\n * \n * @see PluginLifecycle for canonical integration usage.\n */\nexport interface MigrationStep {\n /**\n * Exact ledger map key for this migration and scope.\n */\n key: string;\n /**\n * Initial running migration receipt with immutable checksum.\n */\n record: MigrationRecord;\n /**\n * Reviewed target-dialect SQL executed in order by the host migrate adapter.\n */\n statements: string[] }\n/**\n * Planned host infrastructure change bound to the release and backend digest.\n * \n * @see PluginLifecycle for canonical integration usage.\n */\nexport interface InfrastructureStep {\n /**\n * Infrastructure ledger key for backend/plugin.\n */\n key: string;\n /**\n * Canonical digest binding backend and plugin infrastructure configuration.\n */\n digest: string;\n /**\n * Trusted plugin release declaring infrastructure requirements.\n */\n plugin: LifecyclePlugin;\n /**\n * Exact target whose resources are previewed/applied.\n */\n backend: BackendTarget }\n/**\n * Reviewable hash-bound lifecycle transition generated against one ledger revision.\n * \n * @see PluginLifecycle for canonical integration usage.\n */\nexport interface LifecyclePlan {\n /**\n * Plan discriminator; currently 1.\n */\n format: 1;\n /**\n * Canonical SHA-256 hash of all plan body fields.\n */\n id: string;\n /**\n * Ledger revision observed during planning; apply rejects stale plans.\n */\n revision: number;\n /**\n * Framework compatibility version used to resolve the plan.\n */\n frameworkVersion: string;\n /**\n * Original scoped operation request.\n */\n request: LifecycleRequest;\n /**\n * Snapshot of the exact immutable backend identity.\n */\n backend: BackendTarget\n /**\n * Optional dependency-resolved canonical data contracts and table ownership.\n */\n dataCatalog?: DataContractCatalog\n /**\n * Dependency-ordered trusted feature releases involved in the transition.\n */\n plugins: LifecyclePlugin[];\n /**\n * Ordered migration steps not already applied with matching checksums.\n */\n migrations: MigrationStep[];\n /**\n * Planned host infrastructure changes requiring the configured executor.\n */\n infrastructure: InfrastructureStep[]\n /**\n * Activation map keys disabled before disruptive changes.\n */\n deactivate: string[];\n /**\n * Configured executor identity, or null when none exists.\n */\n infrastructureProvider: string | null;\n /**\n * Always true; lifecycle uninstall never drops business data.\n */\n retainData: true\n}\n/**\n * Host-provided trusted release catalogs, durable lifecycle storage and side-effect adapters.\n * \n * @see PluginLifecycle for canonical integration usage.\n */\nexport interface LifecycleProject {\n /**\n * Cross-process locked atomic durable lifecycle store.\n */\n store: LifecycleStore;\n /**\n * Trusted configured backend catalog; existing physical identities are immutable.\n */\n backends: BackendTarget[];\n /**\n * Trusted registered plugin releases; registration alone grants no tenant activation.\n */\n plugins: LifecyclePlugin[]\n /**\n * Optional canonical schema contract releases, also collected from plugin schemaContracts.\n * \n */\n dataContracts?: readonly DataContract[]\n /**\n * Optional host aliases mapping bundle IDs to ordered registered feature IDs.\n */\n bundles?: Record<string, readonly string[]>\n /**\n * Execute one reviewed migration step on the exact backend; reject failures so reconciliation state is recorded.\n * @param step - Exact planned infrastructure step and target digest; do not reinterpret unreviewed settings.\n * @param backend - Already-provisioned opaque backend declaration; never a connection string or credentials.\n * @returns Resolves without a value after the reviewed host side effect completes.\n * @throws Host adapter or callback failures reject the returned Promise; side effects may already be partially complete.\n */\n migrate: (step: MigrationStep, backend: BackendTarget) => Promise<void>\n /**\n * Optional all-instance admission stop and active-work drain; required before upgrades affecting enabled activations.\n * \n * Stop admission and drain existing work on ALL affected backend instances before upgrades.\n * @param activations - Host operation input bound to the scope described by this member.\n * @returns Resolves without a value after the reviewed host side effect completes.\n * @throws Host adapter or callback failures reject the returned Promise; side effects may already be partially complete.\n */\n quiesce?: (activations: LifecycleState['activations'][string][]) => Promise<void>\n /**\n * Optional named host preview/apply capability; no credentials belong in declarative plugin settings.\n */\n infrastructure?: { \n /**\n * Stable nonsecret infrastructure-provider identity bound into reviewed plans.\n */\n identity: string; \n /**\n * Preview one exact infrastructure step; host must not claim application completion from preview.\n * @param step - Exact reviewed infrastructure step for the configured backend.\n * @returns Host preview information; no apply result is implied.\n * @throws Rejects host adapter failures; effects may already have partially completed.\n \n * @example\n * ```typescript\n * import type { LifecycleProject, InfrastructureStep } from '@alneas/eaos-server/lifecycle-engine';\n * export async function previewInfrastructure(project: LifecycleProject, step: InfrastructureStep) {\n * if (!project.infrastructure) throw new Error(\"Host infrastructure port required\");\n * return project.infrastructure.preview(step);\n * }\n * ```\n */\n preview(step: InfrastructureStep): Promise<unknown>; \n /**\n * Apply one reviewed infrastructure step; errors leave reconciliation state and may follow partial external success.\n * @param step - Exact reviewed infrastructure step for the configured backend.\n * @returns Resolves without a value after host application completes.\n * @throws Rejects host adapter failures; effects may already have partially completed.\n \n * @example\n * ```typescript\n * import type { LifecycleProject, InfrastructureStep } from '@alneas/eaos-server/lifecycle-engine';\n * export async function applyInfrastructure(project: LifecycleProject, step: InfrastructureStep) {\n * if (!project.infrastructure) throw new Error(\"Host infrastructure port required\");\n * await project.infrastructure.apply(step);\n * }\n * ```\n */\n apply(step: InfrastructureStep): Promise<void> }\n}\n/**\n * One registered or historical plugin/backend pair with requested and effective tenant readiness.\n * \n * @see PluginLifecycle for canonical integration usage.\n */\nexport interface LifecycleInventoryEntry {\n /**\n * Registered or historically recorded plugin ID.\n */\n pluginId: string\n /**\n * Backend associated with the entry, or null when no backend is known.\n */\n backendId: string | null\n /**\n * Whether this backend remains in the trusted runtime catalog.\n */\n backendConfigured: boolean\n /**\n * Current registered code version, or null for orphaned history.\n */\n registeredVersion: string | null\n /**\n * Stored installation version, or null before installation.\n */\n installedVersion: string | null\n /**\n * Stored progress or not-installed.\n */\n installationStatus: Installation['status'] | 'not-installed'\n /**\n * Whether stored digest matches registered code, or null without installation.\n */\n releaseMatches: boolean | null\n /**\n * Tenant requestedEnabled flags and effective enabled readiness results.\n */\n tenants: { \n /**\n * Concrete tenant whose activation is inspected.\n */\n tenantId: string; \n /**\n * Stored requested activation flag without readiness guarantees.\n */\n requestedEnabled: boolean; \n /**\n * Effective lifecycle readiness for the registered release and dependency closure.\n */\n enabled: boolean }[]\n}\n/**\n * Read-only revision-bound plugin inventory including code-only and orphaned entries.\n * \n * @see PluginLifecycle for canonical integration usage.\n */\nexport interface LifecycleInventory {\n /**\n * Inventory discriminator; currently 1.\n */\n format: 1\n /**\n * Ledger snapshot revision inspected.\n */\n revision: number\n /**\n * Framework compatibility version used for readiness.\n */\n frameworkVersion: string\n /**\n * Deterministically ordered plugin/backend inventory entries, possibly empty.\n */\n plugins: LifecycleInventoryEntry[]\n}\n/**\n * Reviewable ordered collection of member plans with projected sequential ledger revisions.\n * \n * @see PluginLifecycle for canonical integration usage.\n */\nexport interface LifecycleBundlePlan {\n /**\n * Bundle discriminator; currently 1.\n */\n format: 1;\n /**\n * Canonical digest of bundle identity, operation and member plans.\n */\n id: string;\n /**\n * Registered host bundle alias.\n */\n bundleId: string;\n /**\n * Transition applied to every bundle member.\n */\n operation: Operation;\n /**\n * Dependency-compatible member order; reversed for disable/uninstall.\n */\n plans: LifecyclePlan[] }\nexport * from './backend-migration'\nexport * from '@alneas/eaos-core/contracts/data-contracts'\nexport { dataContractTables, resolveDataContracts, assertDataContractBinding, collectSchemaMigrations, createJsonDocumentAssertion, assertJsonDocumentContracts } from '@alneas/eaos-core/contracts/data-contracts'\n/**\n * Creates independent empty platform tenant, placement and migration maps.\n * @returns A new mutable platform-state object.\n * \n * @example\n * ```typescript\n * import { emptyLifecyclePlatformState } from '@alneas/eaos-server/lifecycle-engine';\n * const platform = emptyLifecyclePlatformState();\n * ```\n */\nexport const emptyLifecyclePlatformState = (): LifecyclePlatformState => ({ tenants: {}, placements: {}, backendMetadata: {}, migrationPlans: {}, migrationRecords: {} })\n/**\n * Creates an independent empty version-1 ledger with revision zero and platform state.\n * @returns A new mutable LifecycleState with empty maps; no persistence is performed.\n * \n * @example\n * ```typescript\n * import { emptyLifecycleState } from '@alneas/eaos-server/lifecycle-engine';\n * const state = emptyLifecycleState();\n * ```\n */\nexport const emptyLifecycleState = (): LifecycleState => ({ format: 1, revision: 0, backends: {}, installations: {}, activations: {}, migrations: {}, infrastructure: {}, platform: emptyLifecyclePlatformState() })\n/**\n * Clones a historical ledger snapshot and fills missing platform maps without rewriting storage.\n * \n * Add fields introduced after the original snapshot format without rewriting old control rows on read.\n * @param input - Historical state snapshot to normalize.\n * @returns A structured clone with a complete platform object; unrelated state validation remains the caller's responsibility.\n * @throws Error for nonobject input or malformed platform/maps; structuredClone errors propagate.\n * \n * @example\n * ```typescript\n * import { emptyLifecycleState, normalizeLifecycleState } from '@alneas/eaos-server/lifecycle-engine';\n * const state = normalizeLifecycleState(emptyLifecycleState());\n * ```\n */\nexport function normalizeLifecycleState(input: LifecycleState): LifecycleState {\n if (!input || typeof input !== 'object') throw new Error('Invalid lifecycle state')\n const state = structuredClone(input) as LifecycleState\n if (state.platform === undefined) state.platform = emptyLifecyclePlatformState()\n if (!state.platform || typeof state.platform !== 'object' || Array.isArray(state.platform)) throw new Error('Invalid lifecycle platform state')\n for (const field of ['tenants', 'placements', 'backendMetadata', 'migrationPlans', 'migrationRecords'] as const) {\n if (state.platform[field] === undefined) state.platform[field] = {}\n if (!state.platform[field] || typeof state.platform[field] !== 'object' || Array.isArray(state.platform[field])) throw new Error(`Invalid lifecycle platform ${field}`)\n }\n return state\n}\n/**\n * Serializes JSON-compatible lifecycle values with recursively sorted object keys.\n * @param value - JSON-serializable primitives, arrays or plain/null-prototype objects; avoid cycles and nonfinite numbers.\n * @returns Deterministic JSON text; array order is preserved.\n * @throws Error for unsupported values/prototypes, JSON serialization failure or recursive cycles.\n * \n * @remarks\n * Uses JSON.stringify primitive semantics, including null for nonfinite numbers. It does not accept undefined/function/symbol values or class instances. Cyclic graphs are unsupported.\n * \n * @example\n * ```typescript\n * import { canonical } from '@alneas/eaos-server/lifecycle-engine';\n * const serialized = canonical({ b: [2, 1], a: true });\n * ```\n */\nexport function canonical(value: unknown): string {\n if (value === null || typeof value !== 'object') {\n const result = JSON.stringify(value)\n if (result === undefined) throw new Error('Lifecycle configuration must be JSON serializable')\n return result\n }\n if (Array.isArray(value)) return '[' + value.map(canonical).join(',') + ']'\n if (Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null) throw new Error('Lifecycle configuration must contain plain objects')\n return '{' + Object.keys(value).sort().map(k => JSON.stringify(k) + ':' + canonical((value as any)[k])).join(',') + '}'\n}\n/**\n * Computes a lowercase SHA-256 digest of the canonical lifecycle JSON representation.\n * @param value - Supported canonical JSON lifecycle configuration.\n * @returns A 64-character lowercase hexadecimal digest.\n * @throws Propagates canonical serialization errors for unsupported values.\n * \n * @remarks\n * Requires Node crypto; the digest proves content identity, not authorization or authenticity.\n * \n * @example\n * ```typescript\n * import { lifecycleDigest } from '@alneas/eaos-server/lifecycle-engine';\n * const digest = lifecycleDigest({ pluginId: 'reports', version: '1.0.0' });\n * ```\n */\nexport const lifecycleDigest = (value: unknown): string => createHash('sha256').update(canonical(value)).digest('hex')\nconst key = (...parts: string[]) => JSON.stringify(parts)\nfunction id(value: string): void { if (!/^[a-zA-Z0-9][a-zA-Z0-9_-]{0,127}$/.test(value)) throw new Error('Invalid lifecycle identifier') }\nfunction assertState(s: LifecycleState): void {\n if (s?.format !== 1 || !Number.isSafeInteger(s.revision) || s.revision < 0 || !s.backends || !s.installations || !s.activations || !s.migrations || !s.infrastructure) throw new Error('Invalid lifecycle state')\n if (s.dataContracts !== undefined) {\n if (!s.dataContracts || typeof s.dataContracts !== 'object' || Array.isArray(s.dataContracts)) throw new Error('Invalid data contract state')\n for (const [recordKey, record] of Object.entries(s.dataContracts)) {\n const parts = JSON.parse(recordKey)\n if (!Array.isArray(parts) || parts.length !== 2 || parts[1] !== record.contract?.id || record.digest !== lifecycleDigest(record.contract) || !['installing', 'installed', 'failed'].includes(record.status)) throw new Error('Invalid data contract state record')\n }\n }\n}\n/**\n * Plans and applies checksum-bound plugin/schema changes against an exclusively locked host ledger.\n * \n * @remarks\n * Server runtime uses Node crypto and semver. The host provides durable cross-process locking, tenant authorization, SQL migration execution and any infrastructure/quiesce adapters. Installation never implies tenant enablement; disable/uninstall retain data. Migration/infrastructure failures persist reconciliation state, and DDL is not rolled back automatically.\n * \n * @example\n * ```typescript\n * import { PluginLifecycle, type LifecycleProject } from '@alneas/eaos-server/lifecycle-engine';\n * export function connectLifecycle(project: LifecycleProject) { return new PluginLifecycle(project); }\n * ```\n */\nexport class PluginLifecycle {\n private readonly plugins: Map<string, LifecyclePlugin>\n private readonly backends: Map<string, BackendTarget>\n private readonly contracts: DataContract[]\n /**\n * Validates and snapshots the registered plugin, backend, contract and bundle catalogs.\n * @param project - Host lifecycle storage, trusted catalogs and execution adapters.\n * @param frameworkVersion - Valid semver framework version; defaults to the installed package version.\n * @throws Error for invalid/duplicate IDs, versions, migrations, conflicting schemas, unsupported backend configuration or unsatisfied contract dependencies.\n * \n * @example\n * ```typescript\n * import { PluginLifecycle, type LifecycleProject } from '@alneas/eaos-server/lifecycle-engine';\n * export function connectLifecycle(project: LifecycleProject) { return new PluginLifecycle(project); }\n * ```\n */\n constructor(private readonly project: LifecycleProject, readonly frameworkVersion = FRAMEWORK_VERSION) {\n if (!valid(frameworkVersion)) throw new Error('Invalid framework version')\n const plugins = JSON.parse(canonical(project.plugins)) as LifecyclePlugin[]\n const backends = JSON.parse(canonical(project.backends)) as BackendTarget[]\n this.plugins = new Map(); this.backends = new Map()\n for (const p of plugins) {\n id(p.id)\n if (this.plugins.has(p.id) || !valid(p.version) || !validRange(p.framework)) throw new Error('Invalid or duplicate plugin release')\n if ((project.dataContracts !== undefined || Object.keys(p.schemaDependencies ?? {}).length) && p.migrations.length) throw new Error(`Contract-backed plugin must put DDL in data contracts: ${p.id}`)\n const migrations = new Set<string>()\n for (const m of p.migrations) {\n id(m.id)\n if (migrations.has(m.id) || !['database', 'tenant'].includes(m.scope)) throw new Error('Invalid or duplicate migration')\n for (const sql of Object.values(m.sql)) if (!Array.isArray(sql) || !sql.length || sql.some(s => typeof s !== 'string' || !s.trim())) throw new Error('Invalid migration SQL')\n migrations.add(m.id)\n }\n const release = { ...p }; delete release.schemaContracts\n this.plugins.set(p.id, release)\n }\n const contracts = new Map<string, DataContract>()\n for (const contract of [...(project.dataContracts ?? []), ...plugins.flatMap(p => p.schemaContracts ?? [])]) {\n const previous = contracts.get(contract.id)\n if (previous && canonical(previous) !== canonical(contract)) throw new Error(`Conflicting data contract definitions: ${contract.id}`)\n contracts.set(contract.id, JSON.parse(canonical(contract)))\n }\n this.contracts = [...contracts.values()]\n resolveDataContracts(this.contracts, Object.fromEntries(this.contracts.map(c => [c.id, c.version])))\n for (const p of plugins) this.catalog([p])\n for (const [bundleId, pluginIds] of Object.entries(project.bundles ?? {})) {\n id(bundleId)\n if (!Array.isArray(pluginIds) || !pluginIds.length || new Set(pluginIds).size !== pluginIds.length || pluginIds.some(pluginId => !this.plugins.has(pluginId))) throw new Error(`Invalid plugin bundle: ${bundleId}`)\n }\n for (const b of backends) {\n id(b.id); id(b.databaseId)\n if (this.backends.has(b.id) || !['sqlite', 'oracle', 'postgres'].includes(b.dialect) || !['shared', 'dedicated'].includes(b.mode)) throw new Error('Invalid backend target')\n if (b.mode === 'dedicated') { if (!b.tenantId) throw new Error('Dedicated backend requires tenant'); id(b.tenantId) }\n else if (b.tenantId !== undefined) throw new Error('Shared backend cannot bind a tenant')\n for (const other of backends) if (other.databaseId === b.databaseId && other.dialect !== b.dialect) throw new Error('Database dialect conflict')\n this.backends.set(b.id, b)\n }\n }\n private bundle(bundleId: string): readonly string[] {\n id(bundleId)\n const pluginIds = this.project.bundles?.[bundleId]\n if (!pluginIds) throw new Error(`Plugin bundle not registered: ${bundleId}`)\n return pluginIds\n }\n /**\n * Plans registered bundle members sequentially against a projected ledger state.\n * @param request - Lifecycle request whose pluginId names a registered bundle.\n * @returns A checksum-bound ordered bundle plan with each member's projected revision.\n * @throws Rejects unknown bundle, invalid member request/state or propagated store failures.\n * \n * @remarks\n * Disable/uninstall reverse bundle order. Planning executes no migrations or writes; projected revisions mirror member apply ordering.\n * \n * @example\n * ```typescript\n * import { PluginLifecycle, type LifecycleRequest } from '@alneas/eaos-server/lifecycle-engine';\n * export function reviewBundle(lifecycle: PluginLifecycle, request: LifecycleRequest) { return lifecycle.planBundle(request); }\n * ```\n */\n async planBundle(request: LifecycleRequest): Promise<LifecycleBundlePlan> {\n const pluginIds = [...this.bundle(request.pluginId)]\n if (request.operation === 'disable' || request.operation === 'uninstall') pluginIds.reverse()\n let projected = await this.project.store.read()\n const plans: LifecyclePlan[] = []\n for (const pluginId of pluginIds) {\n const plan = this.makePlan({ ...request, pluginId }, projected)\n plans.push(plan)\n projected = this.projectBundleState(projected, plan)\n }\n const body = { format: 1 as const, bundleId: request.pluginId, operation: request.operation, plans }\n return JSON.parse(canonical({ ...body, id: lifecycleDigest(body) }))\n }\n\n /**\n * Advance the read-only state used while constructing sequential bundle plans.\n * apply() performs these writes in the same order; mirroring them here keeps\n * each plan's revision and dependency closure valid when applyBundle() runs.\n */\n private projectBundleState(source: LifecycleState, plan: LifecyclePlan): LifecycleState {\n const state = structuredClone(source)\n state.backends[plan.backend.id] = plan.backend\n for (const k of plan.deactivate) if (state.activations[k]) state.activations[k].enabled = false\n\n if (plan.request.operation === 'install' || plan.request.operation === 'update') {\n for (const plugin of plan.plugins) state.installations[key(plan.backend.id, plugin.id)] = { release: plugin, digest: lifecycleDigest(plugin), status: 'installed' }\n if (plan.dataCatalog) {\n state.dataContracts ??= {}\n for (const contract of plan.dataCatalog.contracts) state.dataContracts[key(plan.backend.databaseId, contract.id)] = { contract, digest: lifecycleDigest(contract), status: 'installed' }\n }\n for (const step of plan.migrations) state.migrations[step.key] = { ...step.record, status: 'applied' }\n for (const step of plan.infrastructure) state.infrastructure[step.key] = { digest: step.digest, status: 'applied' }\n state.revision += 2 + (plan.migrations.length * 2) + (plan.infrastructure.length * 2)\n } else if (plan.request.operation === 'enable') {\n for (const plugin of plan.plugins) state.activations[key(plan.backend.id, plan.request.tenantId, plugin.id)] = { backendId: plan.backend.id, tenantId: plan.request.tenantId, pluginId: plugin.id, digest: lifecycleDigest(plugin), enabled: true }\n state.revision += 1\n } else if (plan.request.operation === 'uninstall') {\n delete state.installations[key(plan.backend.id, plan.request.pluginId)]\n state.revision += 1\n } else {\n state.revision += 1\n }\n return state\n }\n /**\n * Validates a reviewed bundle plan and applies its member plans in sequence.\n * @param bundlePlan - Unmodified checksum-bound bundle plan from planBundle.\n * @returns Resolves without a value after every member apply completes.\n * @throws Rejects modified/stale/misordered bundle plans, member apply failures and propagated host errors.\n * \n * @remarks\n * Members acquire their own ledger locks. There is no all-or-nothing bundle transaction; earlier members remain applied if a later member fails. Replan/reconcile before retrying uncertain outcomes.\n * \n * @example\n * ```typescript\n * import { PluginLifecycle, type LifecycleBundlePlan } from '@alneas/eaos-server/lifecycle-engine';\n * export function applyReviewedBundle(lifecycle: PluginLifecycle, plan: LifecycleBundlePlan) { return lifecycle.applyBundle(plan); }\n * ```\n */\n async applyBundle(bundlePlan: LifecycleBundlePlan): Promise<void> {\n const normalized = JSON.parse(canonical(bundlePlan)) as LifecycleBundlePlan\n const pluginIds = this.bundle(normalized.bundleId)\n const expectedIds = normalized.operation === 'disable' || normalized.operation === 'uninstall' ? [...pluginIds].reverse() : [...pluginIds]\n if (normalized.format !== 1 || !['install', 'update', 'enable', 'disable', 'uninstall'].includes(normalized.operation) || normalized.plans.length !== expectedIds.length || normalized.plans.some((plan, index) => plan.request.pluginId !== expectedIds[index] || plan.request.operation !== normalized.operation)) throw new Error('Invalid plugin bundle plan')\n const body = { format: 1 as const, bundleId: normalized.bundleId, operation: normalized.operation, plans: normalized.plans }\n if (lifecycleDigest(body) !== normalized.id) throw new Error('Stale or modified plugin bundle plan')\n for (const plan of normalized.plans) await this.apply(plan)\n }\n private release(id: string): LifecyclePlugin {\n const p = this.plugins.get(id)\n if (!p) throw new Error(`Plugin code not registered: ${id}`)\n if (!satisfies(this.frameworkVersion, p.framework, { includePrerelease: true })) throw new Error(`Incompatible framework for ${id}`)\n return p\n }\n private order(pluginId: string): LifecyclePlugin[] {\n const ordered: LifecyclePlugin[] = [], visited = new Set<string>(), visiting = new Set<string>()\n const visit = (id: string) => {\n if (visiting.has(id)) throw new Error('Plugin dependency cycle')\n if (visited.has(id)) return\n visiting.add(id)\n const p = this.release(id)\n for (const [dependency, range] of Object.entries(p.dependencies ?? {})) {\n if (!validRange(range) || !satisfies(this.release(dependency).version, range, { includePrerelease: true })) throw new Error(`Unsatisfied dependency: ${dependency}`)\n visit(dependency)\n }\n visiting.delete(id); visited.add(id); ordered.push(p)\n }\n visit(pluginId); return ordered\n }\n /**\n * Resolves the canonical schema dependency catalog for registered feature plugins.\n * \n * Read-only complete schema inventory for the selected trusted feature catalog.\n * @param pluginIds - Optional feature IDs; omitted includes all registered plugins, while an empty array selects none.\n * @returns A JSON-cloned dependency-resolved DataContractCatalog.\n * @throws Error for unknown/incompatible feature dependencies or invalid/conflicting contract requirements.\n * \n * @remarks\n * Read-only; schema dependencies never install or enable feature plugins.\n * \n * @example\n * ```typescript\n * import { PluginLifecycle } from '@alneas/eaos-server/lifecycle-engine';\n * export function schemas(lifecycle: PluginLifecycle) { return lifecycle.schemaCatalog(); }\n * ```\n */\n schemaCatalog(pluginIds?: readonly string[]): DataContractCatalog {\n const plugins = pluginIds ? pluginIds.flatMap(id => this.order(id)) : [...this.plugins.values()]\n return JSON.parse(canonical(this.catalog(plugins)))\n }\n private catalog(plugins: LifecyclePlugin[]): DataContractCatalog {\n const requirements: Record<string, string> = {}\n // Check each range independently; combining plugins must never discard a constraint.\n for (const plugin of plugins) {\n resolveDataContracts(this.contracts, plugin.schemaDependencies ?? {})\n Object.assign(requirements, plugin.schemaDependencies ?? {})\n }\n return resolveDataContracts(this.contracts, requirements)\n }\n private contractReady(state: LifecycleState, backend: BackendTarget, tenantId: string, contract: DataContract): boolean {\n const installed = state.dataContracts?.[key(backend.databaseId, contract.id)]\n if (installed?.status !== 'installed' || installed.digest !== lifecycleDigest(contract)) return false\n const identity = contract.migrationIdentity ?? `data-${contract.id}`\n return contract.migrations.every(m => {\n const record = state.migrations[key(backend.databaseId, identity, m.id, m.scope === 'tenant' ? tenantId : '*')]\n return record?.status === 'applied' && record.checksum === lifecycleDigest(m)\n })\n }\n /** Contract ledger identities may retain a feature's historical name even\n * when that feature no longer consumes the contract. Match the actual\n * immutable migration, rather than only the current feature's catalog. */\n private isContractMigration(record: MigrationRecord): boolean {\n return this.contracts.some(contract => {\n if ((contract.migrationIdentity ?? `data-${contract.id}`) !== record.pluginId) return false\n const migration = contract.migrations[record.position]\n return !!migration && migration.id === record.migrationId && lifecycleDigest(migration) === record.checksum && record.status === 'applied'\n })\n }\n private target(request: LifecycleRequest): BackendTarget {\n id(request.pluginId); id(request.backendId); id(request.tenantId)\n if (!['install', 'update', 'enable', 'disable', 'uninstall'].includes(request.operation)) throw new Error('Invalid lifecycle operation')\n const b = this.backends.get(request.backendId)\n if (!b || (b.mode === 'dedicated' && b.tenantId !== request.tenantId)) throw new Error('Backend tenant mismatch or unknown backend')\n return b\n }\n /**\n * Creates a reviewable lifecycle plan from one current ledger snapshot without executing side effects.\n * @param request - Concrete operation, registered plugin/backend and verified tenant; see LifecycleRequest.\n * @returns A deterministic checksum-bound plan carrying the snapshot revision, dependency closure, migrations and retained-data policy.\n * @throws Rejects invalid request/state, incompatible or missing dependencies, changed applied migrations, dirty ledger, unsupported dialect, tenant mismatch or propagated store failures.\n * \n * @remarks\n * Planning is read-only but may become stale immediately. Backend physical identity is immutable. Updates require appended immutable migrations and compatible schema versions; installation and enablement are separate operations.\n * \n * @example\n * ```typescript\n * import { PluginLifecycle, type LifecycleRequest } from '@alneas/eaos-server/lifecycle-engine';\n * export function review(lifecycle: PluginLifecycle, request: LifecycleRequest) { return lifecycle.plan(request); }\n * ```\n */\n async plan(request: LifecycleRequest): Promise<LifecyclePlan> { return this.makePlan(request, await this.project.store.read()) }\n private makePlan(request: LifecycleRequest, state: LifecycleState): LifecyclePlan {\n assertState(state)\n const backend = this.target(request), operation = request.operation\n if (state.backends[backend.id] && canonical(state.backends[backend.id]) !== canonical(backend)) throw new Error('Backend placement is immutable; use a new backend ID and migrate data explicitly')\n for (const b of Object.values(state.backends)) if (b.databaseId === backend.databaseId && b.dialect !== backend.dialect) throw new Error('Database dialect conflict')\n const changing = operation === 'install' || operation === 'update'\n // Disable/uninstall remain available when the new core cannot load an old plugin release.\n const installed = state.installations[key(backend.id, request.pluginId)]\n const plugins = changing || operation === 'enable' ? this.order(request.pluginId) : [installed?.release ?? this.plugins.get(request.pluginId)].filter(Boolean) as LifecyclePlugin[]\n if (!plugins.length) throw new Error('Plugin is not installed')\n if (operation === 'update' && !installed) throw new Error('Install plugin before updating')\n const dataCatalog = this.catalog(plugins)\n for (const table of dataCatalog.tables) {\n for (const [contractKey, installation] of Object.entries(state.dataContracts ?? {})) {\n if (JSON.parse(contractKey)[0] !== backend.databaseId) continue\n if (installation.contract.id !== table.contractId && dataContractTables(installation.contract.schema).has(table.name)) throw new Error(`Installed data contract already owns table: ${table.name}`)\n }\n }\n const migrations: MigrationStep[] = [], infrastructure: InfrastructureStep[] = [], deactivate = new Set<string>()\n const markDependents = (backendId: string, pluginId: string) => {\n const affected = new Set([pluginId]); let changed = true\n while (changed) {\n changed = false\n for (const [k, entry] of Object.entries(state.installations)) {\n if (JSON.parse(k)[0] !== backendId || affected.has(entry.release.id)) continue\n if (Object.keys(entry.release.dependencies ?? {}).some(d => affected.has(d))) { affected.add(entry.release.id); changed = true }\n }\n }\n for (const [k, a] of Object.entries(state.activations)) if (a.backendId === backendId && affected.has(a.pluginId)) deactivate.add(k)\n }\n if (changing) for (const contract of dataCatalog.contracts) {\n const identity = contract.migrationIdentity ?? `data-${contract.id}`\n const old = state.dataContracts?.[key(backend.databaseId, contract.id)]\n if (old && old.status !== 'installed') throw new Error(`Data contract requires reconciliation: ${contract.id}`)\n if (old && old.digest !== lifecycleDigest(contract)) {\n if (old.contract.version === contract.version) throw new Error(`Data contract changed without version bump: ${contract.id}`)\n if (lt(contract.version, old.contract.version)) throw new Error('Data contract downgrade requires explicit migration')\n if (canonical(contract.schema) !== canonical(old.contract.schema) && contract.migrations.length <= old.contract.migrations.length) throw new Error(`Schema changed without an appended migration: ${contract.id}`)\n }\n for (const [installationKey, installation] of Object.entries(state.installations)) {\n if (state.backends[JSON.parse(installationKey)[0]]?.databaseId !== backend.databaseId) continue\n const range = installation.release.schemaDependencies?.[contract.id]\n if (range && !satisfies(contract.version, range)) throw new Error(`Installed plugin requires incompatible data contract: ${installation.release.id}`)\n }\n for (const record of Object.values(state.migrations).filter(m => m.databaseId === backend.databaseId && m.pluginId === identity)) {\n const m = contract.migrations[record.position]\n if (!m || m.id !== record.migrationId || lifecycleDigest(m) !== record.checksum) throw new Error(`Applied contract migration changed or removed: ${record.migrationId}`)\n if (record.status !== 'applied') throw new Error(`Data contract migration requires reconciliation: ${record.migrationId}`)\n }\n for (const [position, m] of contract.migrations.entries()) {\n const statements = m.sql[backend.dialect]\n if (!statements?.length) throw new Error(`Data contract migration ${m.id} does not support ${backend.dialect}`)\n const tenantId = m.scope === 'tenant' ? request.tenantId : null\n const k = key(backend.databaseId, identity, m.id, tenantId ?? '*')\n if (!state.migrations[k]) migrations.push({ key: k, record: { databaseId: backend.databaseId, pluginId: identity, migrationId: m.id, position, tenantId, checksum: lifecycleDigest(m), status: 'running' }, statements })\n }\n if (!old || old.digest !== lifecycleDigest(contract) || contract.migrations.some(m => !state.migrations[key(backend.databaseId, identity, m.id, m.scope === 'tenant' ? request.tenantId : '*')])) {\n for (const activation of Object.values(state.activations)) {\n if (state.backends[activation.backendId]?.databaseId !== backend.databaseId) continue\n const release = state.installations[key(activation.backendId, activation.pluginId)]?.release\n if (release && this.catalog([release]).contracts.some(c => c.id === contract.id)) markDependents(activation.backendId, activation.pluginId)\n }\n }\n }\n if (changing) for (const p of plugins) {\n const digest = lifecycleDigest(p), old = state.installations[key(backend.id, p.id)]\n if (old && old.status !== 'installed') throw new Error(`Installation requires reconciliation: ${p.id}`)\n if (old && old.digest !== digest) {\n if (old.release.version === p.version) throw new Error(`Release changed without version bump: ${p.id}`)\n if (lt(p.version, old.release.version)) throw new Error('Plugin downgrade requires an explicit data migration')\n if (operation === 'install') throw new Error('Use update for an existing release')\n markDependents(backend.id, p.id)\n }\n for (const record of Object.values(state.migrations).filter(m => m.databaseId === backend.databaseId && m.pluginId === p.id && !this.isContractMigration(m))) {\n const m = p.migrations.find(m => m.id === record.migrationId)\n if (!m || p.migrations.indexOf(m) !== record.position || lifecycleDigest(m) !== record.checksum) throw new Error(`Applied migration changed or removed: ${record.migrationId}`)\n if (record.status !== 'applied') throw new Error(`Migration requires reconciliation: ${record.migrationId}`)\n }\n for (const m of p.migrations) {\n const statements = m.sql[backend.dialect]\n if (!statements?.length) throw new Error(`Migration ${m.id} does not support ${backend.dialect}`)\n const tenantId = m.scope === 'tenant' ? request.tenantId : null\n const k = key(backend.databaseId, p.id, m.id, tenantId ?? '*')\n if (!state.migrations[k]) {\n migrations.push({ key: k, record: { databaseId: backend.databaseId, pluginId: p.id, migrationId: m.id, position: p.migrations.indexOf(m), tenantId, checksum: lifecycleDigest(m), status: 'running' }, statements })\n // DDL can affect every running backend sharing this physical DB.\n if (m.scope === 'database') for (const b of Object.values(state.backends)) if (b.databaseId === backend.databaseId) markDependents(b.id, p.id)\n }\n }\n if (p.infrastructure) {\n const k = key(backend.id, p.id), digest = lifecycleDigest({ backend, plugin: p })\n if (state.infrastructure[k] && state.infrastructure[k].status !== 'applied') throw new Error('Infrastructure requires reconciliation')\n if (state.infrastructure[k]?.digest !== digest) infrastructure.push({ key: k, digest, plugin: p, backend })\n }\n }\n if (operation === 'disable' || operation === 'uninstall') {\n const dependents = Object.values(state.activations).filter(a => a.backendId === backend.id && a.tenantId === request.tenantId && a.enabled && a.pluginId !== request.pluginId && this.dependsOn(state, backend.id, a.pluginId, request.pluginId))\n if (dependents.length) throw new Error('Disable dependent plugins first')\n const activation = key(backend.id, request.tenantId, request.pluginId)\n if (operation === 'disable') deactivate.add(activation)\n else {\n if (Object.values(state.activations).some(a => a.backendId === backend.id && a.pluginId === request.pluginId && a.enabled)) throw new Error('Disable plugin for every tenant on this backend before uninstalling')\n if (Object.entries(state.installations).some(([k, i]) => JSON.parse(k)[0] === backend.id && i.release.id !== request.pluginId && this.dependsOn(state, backend.id, i.release.id, request.pluginId))) throw new Error('Uninstall dependent plugins first')\n }\n }\n if (operation === 'enable') for (const p of plugins) if (!this.ready(state, backend, request.tenantId, p)) throw new Error(`Install/migrate compatible release before enabling: ${p.id}`)\n const body = { format: 1 as const, revision: state.revision, frameworkVersion: this.frameworkVersion, request: { ...request }, backend, ...(dataCatalog.contracts.length ? { dataCatalog } : {}), plugins, migrations, infrastructure, deactivate: [...deactivate].sort(), infrastructureProvider: this.project.infrastructure?.identity ?? null, retainData: true as const }\n return JSON.parse(canonical({ ...body, id: lifecycleDigest(body) }))\n }\n private dependsOn(state: LifecycleState, backendId: string, pluginId: string, target: string, seen = new Set<string>()): boolean {\n if (seen.has(pluginId)) return false\n seen.add(pluginId)\n return Object.keys(state.installations[key(backendId, pluginId)]?.release.dependencies ?? {}).some(d => d === target || this.dependsOn(state, backendId, d, target, seen))\n }\n private ready(state: LifecycleState, backend: BackendTarget, tenantId: string, p: LifecyclePlugin): boolean {\n const installed = state.installations[key(backend.id, p.id)]\n if (installed?.status !== 'installed' || installed.digest !== lifecycleDigest(p)) return false\n if (Object.values(state.migrations).some(m => m.databaseId === backend.databaseId && m.pluginId === p.id && !this.isContractMigration(m) && (m.status !== 'applied' || !p.migrations.some(definition => definition.id === m.migrationId && p.migrations.indexOf(definition) === m.position && lifecycleDigest(definition) === m.checksum)))) return false\n return this.catalog([p]).contracts.every(c => this.contractReady(state, backend, tenantId, c)) && p.migrations.every(m => {\n const record = state.migrations[key(backend.databaseId, p.id, m.id, m.scope === 'tenant' ? tenantId : '*')]\n return record?.status === 'applied' && record.checksum === lifecycleDigest(m)\n }) && (!p.infrastructure || state.infrastructure[key(backend.id, p.id)]?.digest === lifecycleDigest({ backend, plugin: p }) && state.infrastructure[key(backend.id, p.id)]?.status === 'applied')\n }\n /**\n * Checks that a tenant activation and its entire registered dependency closure match ready ledger releases.\n * @param backendId - Registered execution backend ID.\n * @param tenantId - Verified concrete tenant ID.\n * @param pluginId - Registered feature ID to check.\n * @returns True only when matching installation, migrations, infrastructure and activation digests are all ready; false for missing/incompatible readiness.\n * @throws Rejects malformed IDs/state, unknown or mismatched backend/tenant and store failures.\n * \n * @remarks\n * Read-only admission check; a later state change can revoke access. Host must still enforce current tenant/resource authorization.\n * \n * @example\n * ```typescript\n * import { PluginLifecycle } from '@alneas/eaos-server/lifecycle-engine';\n * export function admitted(lifecycle: PluginLifecycle, backendId: string, tenantId: string, pluginId: string) { return lifecycle.isEnabled(backendId, tenantId, pluginId); }\n * ```\n */\n async isEnabled(backendId: string, tenantId: string, pluginId: string): Promise<boolean> {\n const state = await this.project.store.read(); assertState(state)\n return this.enabledInState(state, backendId, tenantId, pluginId)\n }\n private enabledInState(state: LifecycleState, backendId: string, tenantId: string, pluginId: string): boolean {\n const backend = this.target({ operation: 'enable', backendId, tenantId, pluginId })\n if (!state.backends[backend.id] || canonical(state.backends[backend.id]) !== canonical(backend)) return false\n let plugins: LifecyclePlugin[]\n try { plugins = this.order(pluginId) } catch { return false }\n return plugins.every(p => this.ready(state, backend, tenantId, p) && state.activations[key(backendId, tenantId, p.id)]?.enabled === true && state.activations[key(backendId, tenantId, p.id)]?.digest === lifecycleDigest(p))\n }\n /**\n * Reads inventory including registered uninstalled code and orphaned historical installations.\n * \n * One read-only control-state snapshot; includes orphaned installation records and registered, uninstalled code.\n * @param options - Optional backendId and tenantId filters; omitted returns all known inventory.\n * @returns A revision-bound inventory with effective enabled state distinct from requested activation.\n * @throws Rejects invalid filter IDs, unknown backend, corrupt installation/activation records, dedicated tenant mismatch or store failure.\n * \n * @remarks\n * Performs one ledger read without writes. Dedicated backends for another tenant are omitted unless explicitly requested, in which case the request rejects.\n * \n * @example\n * ```typescript\n * import { PluginLifecycle } from '@alneas/eaos-server/lifecycle-engine';\n * export function inventory(lifecycle: PluginLifecycle) { return lifecycle.list(); }\n * ```\n */\n async list(options: { \n /**\n * Optional exact backend filter; unknown backends reject.\n */\n backendId?: string; \n /**\n * Optional concrete tenant filter; dedicated backend scope must match.\n */\n tenantId?: string } = {}): Promise<LifecycleInventory> {\n if (options.backendId !== undefined) id(options.backendId)\n if (options.tenantId !== undefined) id(options.tenantId)\n const state = await this.project.store.read(); assertState(state)\n const installations = Object.entries(state.installations).map(([entryKey, installation]) => {\n const parts = JSON.parse(entryKey)\n if (!Array.isArray(parts) || parts.length !== 2 || parts.some(p => typeof p !== 'string')) throw new Error('Invalid installation key')\n const [backendId, pluginId] = parts as [string, string]\n id(backendId); id(pluginId)\n if (installation.release?.id !== pluginId || !valid(installation.release.version) || !['installing', 'installed', 'failed'].includes(installation.status)) throw new Error('Invalid installation record')\n return { backendId, pluginId }\n })\n const activations = Object.values(state.activations)\n const backendIds = new Set([...this.backends.keys(), ...Object.keys(state.backends), ...installations.map(p => p.backendId), ...activations.map(p => p.backendId)])\n for (const backendId of backendIds) id(backendId)\n for (const activation of activations) {\n id(activation.tenantId); id(activation.pluginId)\n if (typeof activation.enabled !== 'boolean') throw new Error('Invalid activation record')\n }\n if (options.backendId && !backendIds.has(options.backendId)) throw new Error(`Unknown backend: ${options.backendId}`)\n const targets: (string | null)[] = options.backendId ? [options.backendId] : backendIds.size ? [...backendIds].sort() : [null]\n const plugins: LifecycleInventoryEntry[] = []\n for (const backendId of targets) {\n const backend = backendId ? this.backends.get(backendId) : undefined\n if (options.tenantId && backend?.mode === 'dedicated' && backend.tenantId !== options.tenantId) {\n if (options.backendId) throw new Error('Tenant does not belong to dedicated backend')\n continue\n }\n const pluginIds = new Set([...this.plugins.keys(), ...installations.filter(p => p.backendId === backendId).map(p => p.pluginId), ...activations.filter(p => p.backendId === backendId).map(p => p.pluginId)])\n for (const pluginId of [...pluginIds].sort()) {\n const registered = this.plugins.get(pluginId)\n const installed = backendId ? state.installations[key(backendId, pluginId)] : undefined\n const tenantIds = options.tenantId ? [options.tenantId] : [...new Set(activations.filter(p => p.backendId === backendId && p.pluginId === pluginId).map(p => p.tenantId))].sort()\n plugins.push({\n pluginId, backendId, backendConfigured: !!backend,\n registeredVersion: registered?.version ?? null, installedVersion: installed?.release.version ?? null,\n installationStatus: installed?.status ?? 'not-installed',\n releaseMatches: installed ? !!registered && installed.digest === lifecycleDigest(registered) : null,\n tenants: tenantIds.map(tenantId => ({\n tenantId, requestedEnabled: backendId ? state.activations[key(backendId, tenantId, pluginId)]?.enabled === true : false,\n enabled: !!backend && !!backendId && (backend.mode !== 'dedicated' || backend.tenantId === tenantId) && this.enabledInState(state, backendId, tenantId, pluginId),\n })),\n })\n }\n }\n return { format: 1, revision: state.revision, frameworkVersion: this.frameworkVersion, plugins }\n }\n /**\n * Runs a host callback only after the current plugin dependency closure passes lifecycle admission.\n * @typeParam T - Value resolved by the admitted callback.\n * @param backendId - Registered backend ID.\n * @param tenantId - Verified concrete tenant ID.\n * @param pluginId - Feature plugin ID.\n * @param callback - Async work invoked once after admission; must enforce tenant/resource authorization itself.\n * @returns The callback result without cloning.\n * @throws Rejects inactive plugin, lifecycle/store validation failure or callback rejection.\n * \n * @remarks\n * The admission check does not hold a lock or pin activation throughout callback execution. Host quiesce/drain and live authorization remain required.\n * \n * @example\n * ```typescript\n * import { PluginLifecycle } from '@alneas/eaos-server/lifecycle-engine';\n * export function runAdmitted<T>(lifecycle: PluginLifecycle, backendId: string, tenantId: string, pluginId: string, work: () => Promise<T>) { return lifecycle.run(backendId, tenantId, pluginId, work); }\n * ```\n */\n async run<T>(backendId: string, tenantId: string, pluginId: string, callback: () => Promise<T>): Promise<T> {\n if (!await this.isEnabled(backendId, tenantId, pluginId)) throw new Error('Plugin is inactive')\n return callback()\n }\n /**\n * Checks plan freshness and invokes host infrastructure previews without applying ledger changes.\n * @param plan - Unmodified lifecycle plan to preview.\n * @returns Preview results in infrastructure-step order, or an empty array when no infrastructure is needed.\n * @throws Rejects stale/modified plan, missing infrastructure adapter or propagated plan/preview errors.\n * \n * @remarks\n * Infrastructure previews run concurrently through Promise.all. Host preview adapters own any external read/preview effects; this method executes no migrations.\n * \n * @example\n * ```typescript\n * import { PluginLifecycle, type LifecyclePlan } from '@alneas/eaos-server/lifecycle-engine';\n * export function preview(lifecycle: PluginLifecycle, plan: LifecyclePlan) { return lifecycle.preview(plan); }\n * ```\n */\n async preview(plan: LifecyclePlan): Promise<unknown[]> {\n const fresh = await this.plan(plan.request)\n if (canonical(fresh) !== canonical(plan)) throw new Error('Stale or modified lifecycle plan')\n if (plan.infrastructure.length && !this.project.infrastructure) throw new Error('Infrastructure executor is required')\n return Promise.all(plan.infrastructure.map(s => this.project.infrastructure!.preview(s)))\n }\n /**\n * Revalidates and executes a reviewed lifecycle plan while holding the host's exclusive ledger lock.\n * @param plan - Unmodified plan bound to the current ledger revision and registered configuration.\n * @returns Resolves without a value after ledger updates and requested side effects complete.\n * @throws Rejects stale/modified plan, missing executors/quiesce, reconciliation conflicts or host store, migration, infrastructure or drain failures.\n * \n * @remarks\n * Before upgrade side effects, affected activations are disabled durably and all-instance quiesce is required. Infrastructure/migration running/applied/failed receipts are persisted separately. Errors can follow partial external success; no automatic rollback/retry occurs. Uninstall retains business data and migration history.\n * \n * @example\n * ```typescript\n * import { PluginLifecycle, type LifecyclePlan } from '@alneas/eaos-server/lifecycle-engine';\n * export function applyReviewed(lifecycle: PluginLifecycle, plan: LifecyclePlan) { return lifecycle.apply(plan); }\n * ```\n */\n async apply(plan: LifecyclePlan): Promise<void> {\n plan = JSON.parse(canonical(plan))\n await this.project.store.withLock(async writer => {\n const state = await writer.read(), fresh = this.makePlan(plan.request, state)\n if (canonical(fresh) !== canonical(plan)) throw new Error('Stale or modified lifecycle plan')\n if (plan.infrastructure.length && !this.project.infrastructure) throw new Error('Infrastructure executor is required')\n if (['install', 'update'].includes(plan.request.operation) && plan.deactivate.length && !this.project.quiesce) throw new Error('A quiesce executor is required for active deployments')\n const save = async () => { state.revision++; await writer.write(state) }\n const { request, backend } = plan\n state.backends[backend.id] = backend\n for (const k of plan.deactivate) if (state.activations[k]) state.activations[k].enabled = false\n if (request.operation === 'install' || request.operation === 'update') {\n for (const p of plan.plugins) state.installations[key(backend.id, p.id)] = { release: p, digest: lifecycleDigest(p), status: 'installing' }\n state.dataContracts ??= {}\n for (const contract of plan.dataCatalog?.contracts ?? []) state.dataContracts[key(backend.databaseId, contract.id)] = { contract, digest: lifecycleDigest(contract), status: 'installing' }\n // Persist inactive status BEFORE any DB or infrastructure effects.\n await save()\n try {\n if (plan.deactivate.length) await this.project.quiesce!(plan.deactivate.map(k => state.activations[k]))\n for (const step of plan.infrastructure) {\n state.infrastructure[step.key] = { digest: step.digest, status: 'running' }; await save()\n try { await this.project.infrastructure!.apply(step) }\n catch (error) { state.infrastructure[step.key].status = 'failed'; await save(); throw error }\n state.infrastructure[step.key].status = 'applied'; await save()\n }\n for (const step of plan.migrations) {\n state.migrations[step.key] = { ...step.record }; await save()\n try { await this.project.migrate(step, backend) }\n catch (error) { state.migrations[step.key].status = 'failed'; await save(); throw error }\n state.migrations[step.key].status = 'applied'; await save()\n }\n for (const contract of plan.dataCatalog?.contracts ?? []) state.dataContracts![key(backend.databaseId, contract.id)].status = 'installed'\n for (const p of plan.plugins) state.installations[key(backend.id, p.id)].status = 'installed'\n } catch (error) {\n for (const contract of plan.dataCatalog?.contracts ?? []) state.dataContracts![key(backend.databaseId, contract.id)].status = 'failed'\n for (const p of plan.plugins) state.installations[key(backend.id, p.id)].status = 'failed'\n await save(); throw error\n }\n } else if (request.operation === 'enable') {\n for (const p of plan.plugins) state.activations[key(backend.id, request.tenantId, p.id)] = { backendId: backend.id, tenantId: request.tenantId, pluginId: p.id, digest: lifecycleDigest(p), enabled: true }\n } else if (request.operation === 'uninstall') delete state.installations[key(backend.id, request.pluginId)]\n await save()\n })\n }\n}\n","{\n \"name\": \"@alneas/eaos-server\",\n \"version\": \"0.1.0\",\n \"type\": \"module\",\n \"license\": \"MIT\",\n \"description\": \"EAOS server public package\",\n \"exports\": {\n \"./db/local-first-sqlite-adapter\": {\n \"types\": \"./dist/db-package/db/local-first-sqlite-adapter.d.ts\",\n \"import\": \"./dist/db-package/db/local-first-sqlite-adapter.js\"\n },\n \"./db\": {\n \"types\": \"./dist/db-package/index.d.ts\",\n \"import\": \"./dist/db-package/index.js\"\n },\n \"./db/migration/aggregator\": {\n \"types\": \"./dist/db-package/migration/aggregator.d.ts\",\n \"import\": \"./dist/db-package/migration/aggregator.js\"\n },\n \"./db/migration\": {\n \"types\": \"./dist/db-package/migration/index.d.ts\",\n \"import\": \"./dist/db-package/migration/index.js\"\n },\n \"./lifecycle-engine/backend-migration\": {\n \"types\": \"./dist/lifecycle-engine/backend-migration.d.ts\",\n \"import\": \"./dist/lifecycle-engine/backend-migration.js\"\n },\n \"./lifecycle-engine\": {\n \"types\": \"./dist/lifecycle-engine/index.d.ts\",\n \"import\": \"./dist/lifecycle-engine/index.js\"\n },\n \"./platform/artifacts\": {\n \"types\": \"./dist/lifecycle-engine/platform/artifacts.d.ts\",\n \"import\": \"./dist/lifecycle-engine/platform/artifacts.js\"\n },\n \"./platform/control-plane\": {\n \"types\": \"./dist/lifecycle-engine/platform/control-plane.d.ts\",\n \"import\": \"./dist/lifecycle-engine/platform/control-plane.js\"\n },\n \"./platform/database-router\": {\n \"types\": \"./dist/lifecycle-engine/platform/database-router.d.ts\",\n \"import\": \"./dist/lifecycle-engine/platform/database-router.js\"\n },\n \"./platform/deployment-placements\": {\n \"types\": \"./dist/lifecycle-engine/platform/deployment-placements.d.ts\",\n \"import\": \"./dist/lifecycle-engine/platform/deployment-placements.js\"\n },\n \"./platform/deployment\": {\n \"types\": \"./dist/lifecycle-engine/platform/deployment.d.ts\",\n \"import\": \"./dist/lifecycle-engine/platform/deployment.js\"\n },\n \"./platform\": {\n \"types\": \"./dist/lifecycle-engine/platform/index.d.ts\",\n \"import\": \"./dist/lifecycle-engine/platform/index.js\"\n },\n \"./platform/runtime\": {\n \"types\": \"./dist/lifecycle-engine/platform/runtime.d.ts\",\n \"import\": \"./dist/lifecycle-engine/platform/runtime.js\"\n },\n \"./platform/site-publication\": {\n \"types\": \"./dist/lifecycle-engine/platform/site-publication.d.ts\",\n \"import\": \"./dist/lifecycle-engine/platform/site-publication.js\"\n },\n \"./platform/user-directory\": {\n \"types\": \"./dist/lifecycle-engine/platform/user-directory.d.ts\",\n \"import\": \"./dist/lifecycle-engine/platform/user-directory.js\"\n },\n \"./lifecycle-engine/baseline\": {\n \"types\": \"./dist/lifecycle-engine/baseline.d.ts\",\n \"import\": \"./dist/lifecycle-engine/baseline.js\"\n },\n \"./storage\": {\n \"types\": \"./dist/storage/index.d.ts\",\n \"import\": \"./dist/storage/index.js\"\n },\n \"./storage/s3-compatible\": {\n \"types\": \"./dist/storage/s3-compatible.d.ts\",\n \"import\": \"./dist/storage/s3-compatible.js\"\n },\n \"./agentic/agent-jobs\": {\n \"types\": \"./dist/agentic/agent-jobs.d.ts\",\n \"import\": \"./dist/agentic/agent-jobs.js\"\n },\n \"./agentic/agent-node\": {\n \"types\": \"./dist/agentic/agent-node.d.ts\",\n \"import\": \"./dist/agentic/agent-node.js\"\n },\n \"./agentic/agent-runner\": {\n \"types\": \"./dist/agentic/agent-runner.d.ts\",\n \"import\": \"./dist/agentic/agent-runner.js\"\n },\n \"./agentic/ai-broker\": {\n \"types\": \"./dist/agentic/ai-broker.d.ts\",\n \"import\": \"./dist/agentic/ai-broker.js\"\n },\n \"./agentic/atomic-checkpointer\": {\n \"types\": \"./dist/agentic/atomic-checkpointer.d.ts\",\n \"import\": \"./dist/agentic/atomic-checkpointer.js\"\n },\n \"./agentic/autonomous-worker\": {\n \"types\": \"./dist/agentic/autonomous-worker.d.ts\",\n \"import\": \"./dist/agentic/autonomous-worker.js\"\n },\n \"./agentic/event-bridge\": {\n \"types\": \"./dist/agentic/event-bridge.d.ts\",\n \"import\": \"./dist/agentic/event-bridge.js\"\n },\n \"./agentic/executor\": {\n \"types\": \"./dist/agentic/executor.d.ts\",\n \"import\": \"./dist/agentic/executor.js\"\n },\n \"./agentic/graph-projection\": {\n \"types\": \"./dist/agentic/graph-projection.d.ts\",\n \"import\": \"./dist/agentic/graph-projection.js\"\n },\n \"./agentic/graph\": {\n \"types\": \"./dist/agentic/graph.d.ts\",\n \"import\": \"./dist/agentic/graph.js\"\n },\n \"./agentic\": {\n \"types\": \"./dist/agentic/index.d.ts\",\n \"import\": \"./dist/agentic/index.js\"\n },\n \"./agentic/local-runner\": {\n \"types\": \"./dist/agentic/local-runner.d.ts\",\n \"import\": \"./dist/agentic/local-runner.js\"\n },\n \"./agentic/remote-executor\": {\n \"types\": \"./dist/agentic/remote-executor.d.ts\",\n \"import\": \"./dist/agentic/remote-executor.js\"\n },\n \"./agentic/types\": {\n \"types\": \"./dist/agentic/types.d.ts\",\n \"import\": \"./dist/agentic/types.js\"\n },\n \"./agentic/workflow-catalog\": {\n \"types\": \"./dist/agentic/workflow-catalog.d.ts\",\n \"import\": \"./dist/agentic/workflow-catalog.js\"\n },\n \"./agentic/workflow-compiler\": {\n \"types\": \"./dist/agentic/workflow-compiler.d.ts\",\n \"import\": \"./dist/agentic/workflow-compiler.js\"\n },\n \"./agentic/workflow-coordinator\": {\n \"types\": \"./dist/agentic/workflow-coordinator.d.ts\",\n \"import\": \"./dist/agentic/workflow-coordinator.js\"\n },\n \"./agentic/workflow-manager\": {\n \"types\": \"./dist/agentic/workflow-manager.d.ts\",\n \"import\": \"./dist/agentic/workflow-manager.js\"\n },\n \"./agentic/workflow-registry\": {\n \"types\": \"./dist/agentic/workflow-registry.d.ts\",\n \"import\": \"./dist/agentic/workflow-registry.js\"\n },\n \"./auth-hooks/api-key\": {\n \"types\": \"./dist/auth-hooks/api-key.d.ts\",\n \"import\": \"./dist/auth-hooks/api-key.js\"\n },\n \"./auth-hooks\": {\n \"types\": \"./dist/auth-hooks/index.d.ts\",\n \"import\": \"./dist/auth-hooks/index.js\"\n },\n \"./browser-auth/account-memberships\": {\n \"types\": \"./dist/browser-auth/account-memberships.d.ts\",\n \"import\": \"./dist/browser-auth/account-memberships.js\"\n },\n \"./browser-auth\": {\n \"types\": \"./dist/browser-auth/index.d.ts\",\n \"import\": \"./dist/browser-auth/index.js\"\n },\n \"./browser-auth/kratos-session\": {\n \"types\": \"./dist/browser-auth/kratos-session.d.ts\",\n \"import\": \"./dist/browser-auth/kratos-session.js\"\n },\n \"./browser-auth/platform-session\": {\n \"types\": \"./dist/browser-auth/platform-session.d.ts\",\n \"import\": \"./dist/browser-auth/platform-session.js\"\n },\n \"./browser-auth/public-memberships\": {\n \"types\": \"./dist/browser-auth/public-memberships.d.ts\",\n \"import\": \"./dist/browser-auth/public-memberships.js\"\n },\n \"./cache\": {\n \"types\": \"./dist/cache/index.d.ts\",\n \"import\": \"./dist/cache/index.js\"\n },\n \"./engine\": {\n \"types\": \"./dist/engine.d.ts\",\n \"import\": \"./dist/engine.js\"\n },\n \"./execution\": {\n \"types\": \"./dist/execution/index.d.ts\",\n \"import\": \"./dist/execution/index.js\"\n },\n \"./extensions\": {\n \"types\": \"./dist/extensions/index.d.ts\",\n \"import\": \"./dist/extensions/index.js\"\n },\n \"./health\": {\n \"types\": \"./dist/health/index.d.ts\",\n \"import\": \"./dist/health/index.js\"\n },\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\"\n },\n \"./lifecycle\": {\n \"types\": \"./dist/lifecycle/index.d.ts\",\n \"import\": \"./dist/lifecycle/index.js\"\n },\n \"./mcp\": {\n \"types\": \"./dist/mcp.d.ts\",\n \"import\": \"./dist/mcp.js\"\n },\n \"./middleware/auth\": {\n \"types\": \"./dist/middleware/auth.d.ts\",\n \"import\": \"./dist/middleware/auth.js\"\n },\n \"./middleware/error-handler\": {\n \"types\": \"./dist/middleware/error-handler.d.ts\",\n \"import\": \"./dist/middleware/error-handler.js\"\n },\n \"./middleware/module-guard\": {\n \"types\": \"./dist/middleware/module-guard.d.ts\",\n \"import\": \"./dist/middleware/module-guard.js\"\n },\n \"./platform-admin\": {\n \"types\": \"./dist/platform-admin/index.d.ts\",\n \"import\": \"./dist/platform-admin/index.js\"\n },\n \"./platform-admin/store\": {\n \"types\": \"./dist/platform-admin/store.d.ts\",\n \"import\": \"./dist/platform-admin/store.js\"\n },\n \"./plugin-data/annotations\": {\n \"types\": \"./dist/plugin-data/annotations.d.ts\",\n \"import\": \"./dist/plugin-data/annotations.js\"\n },\n \"./plugin-data/atomic-context\": {\n \"types\": \"./dist/plugin-data/atomic-context.d.ts\",\n \"import\": \"./dist/plugin-data/atomic-context.js\"\n },\n \"./plugin-data/atomic\": {\n \"types\": \"./dist/plugin-data/atomic.d.ts\",\n \"import\": \"./dist/plugin-data/atomic.js\"\n },\n \"./plugin-data/audit\": {\n \"types\": \"./dist/plugin-data/audit.d.ts\",\n \"import\": \"./dist/plugin-data/audit.js\"\n },\n \"./plugin-data/commands\": {\n \"types\": \"./dist/plugin-data/commands.d.ts\",\n \"import\": \"./dist/plugin-data/commands.js\"\n },\n \"./plugin-data/composite\": {\n \"types\": \"./dist/plugin-data/composite.d.ts\",\n \"import\": \"./dist/plugin-data/composite.js\"\n },\n \"./plugin-data/delivery\": {\n \"types\": \"./dist/plugin-data/delivery.d.ts\",\n \"import\": \"./dist/plugin-data/delivery.js\"\n },\n \"./plugin-data\": {\n \"types\": \"./dist/plugin-data/index.d.ts\",\n \"import\": \"./dist/plugin-data/index.js\"\n },\n \"./plugin-data/json-documents\": {\n \"types\": \"./dist/plugin-data/json-documents.d.ts\",\n \"import\": \"./dist/plugin-data/json-documents.js\"\n },\n \"./plugin-data/outbox\": {\n \"types\": \"./dist/plugin-data/outbox.d.ts\",\n \"import\": \"./dist/plugin-data/outbox.js\"\n },\n \"./plugin-data/scoped-records\": {\n \"types\": \"./dist/plugin-data/scoped-records.d.ts\",\n \"import\": \"./dist/plugin-data/scoped-records.js\"\n },\n \"./sql-lifecycle\": {\n \"types\": \"./dist/sql-lifecycle/index.d.ts\",\n \"import\": \"./dist/sql-lifecycle/index.js\"\n },\n \"./tenant\": {\n \"types\": \"./dist/tenant.d.ts\",\n \"import\": \"./dist/tenant.js\"\n },\n \"./workspace-context\": {\n \"types\": \"./dist/workspace-context.d.ts\",\n \"import\": \"./dist/workspace-context.js\"\n },\n \"./entitlements\": {\n \"types\": \"./dist/entitlements/index.d.ts\",\n \"import\": \"./dist/entitlements/index.js\"\n },\n \"./plugin-sdk\": {\n \"types\": \"./dist/plugin-sdk.d.ts\",\n \"import\": \"./dist/plugin-sdk.js\"\n }\n },\n \"files\": [\n \"dist\",\n \"docs\",\n \"README.md\",\n \"LICENSE\",\n \"CHANGELOG.md\",\n \"README.ja.md\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"test\": \"bun test\"\n },\n \"publishConfig\": {\n \"registry\": \"https://registry.npmjs.org\",\n \"access\": \"public\"\n },\n \"engines\": {\n \"node\": \">=24.0.0\"\n },\n \"devDependencies\": {\n \"tsup\": \"^9.0.0\",\n \"typescript\": \"^6.0.3\",\n \"@types/node\": \"^22.20.5\",\n \"@types/semver\": \"^7.8.0\",\n \"@alneas/appkit-core\": \"0.2.0\"\n },\n \"dependencies\": {\n \"@alneas/eaos-core\": \"^0.1.0\",\n \"semver\": \"^7.8.5\",\n \"hono\": \"^4.13.13\",\n \"ajv\": \"^8.20.0\",\n \"ajv-formats\": \"^3.0.1\",\n \"@langchain/langgraph\": \"^1.5.0\"\n },\n \"peerDependencies\": {\n \"@alneas/appkit-core\": \"0.2.0\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/dataarthub/eaos.git\",\n \"directory\": \"packages/server\"\n },\n \"homepage\": \"https://tech-docs.alneas.com/eaos-workspace/\",\n \"bugs\": {\n \"url\": \"https://github.com/dataarthub/eaos/issues\"\n }\n}\n","import { lifecycleDigest, type BackendTarget } from './index'\n\n/**\n * Explicit complete fleet or nonempty concrete tenant selection for a reviewed data move.\n * \n * @see planBackendMigration for canonical integration usage.\n */\nexport type BackendMigrationScope =\n | { \n /**\n * Scope discriminator: all-tenants includes the fleet; tenants names a concrete bounded selection.\n */\n kind: 'all-tenants' }\n | { \n /**\n * Scope discriminator: all-tenants includes the fleet; tenants names a concrete bounded selection.\n */\n kind: 'tenants'; \n /**\n * Nonempty distinct concrete tenant IDs; dedicated endpoint tenants must be included.\n */\n tenantIds: readonly string[] }\n\n/**\n * Operator-reviewed source/target database move with bounded scope and reason.\n * \n * @see planBackendMigration for canonical integration usage.\n */\nexport interface BackendMigrationRequest {\n /**\n * Nonblank stable migration identity, up to 256 characters.\n */\n migrationId: string\n /**\n * Existing backend whose data remains retained.\n */\n source: BackendTarget\n /**\n * Different backend and physical database identity.\n */\n target: BackendTarget\n /**\n * All tenants or nonempty unique explicit tenant IDs; dedicated endpoints require their tenant in explicit scope.\n */\n scope: BackendMigrationScope\n /**\n * Nonempty unique registered-style feature IDs covered by the move.\n */\n pluginIds: readonly string[]\n /**\n * Parseable request timestamp.\n */\n requestedAt: string\n /**\n * Nonblank reviewed operator reason, at most 1024 characters.\n */\n reason: string\n}\n\n/**\n * Deterministic five-phase non-destructive data migration plan.\n * \n * @see planBackendMigration for canonical integration usage.\n */\nexport interface BackendMigrationPlan {\n /**\n * Plan discriminator; currently 1.\n */\n format: 1\n /**\n * Canonical digest of the normalized request and phase/safety flags.\n */\n id: string\n /**\n * Cloned request with sorted plugin and explicit tenant IDs.\n */\n request: BackendMigrationRequest\n /**\n * Ordered prepare/copy/verify/cutover/retain-source execution phases.\n */\n phases: readonly ['prepare', 'copy', 'verify', 'cutover', 'retain-source']\n /**\n * Always true; the host must drain affected execution before switching.\n */\n requiresQuiesce: true\n /**\n * Always true; source data must remain available.\n */\n retainSourceData: true\n /**\n * Always false; dropping source data is outside this plan.\n */\n destructiveOperations: false\n}\n\n/**\n * Host-reported match for one tenant/plugin copy at observed revisions.\n * \n * @see planBackendMigration for canonical integration usage.\n */\nexport interface BackendMigrationVerification {\n /**\n * Concrete verified tenant covered by the plan.\n */\n tenantId: string\n /**\n * Planned feature whose records were compared.\n */\n pluginId: string\n /**\n * Nonnegative safe revision observed at source.\n */\n sourceRevision: number\n /**\n * Nonnegative safe revision observed at target; not required to numerically equal source.\n */\n targetRevision: number\n /**\n * True only when the host comparison passed; validator does not perform the comparison.\n */\n matched: boolean\n}\n\n/**\n * Host verification evidence bound to a reviewed source/target migration.\n * \n * @see planBackendMigration for canonical integration usage.\n */\nexport interface BackendMigrationVerificationReport {\n /**\n * Plan request migration identity.\n */\n migrationId: string\n /**\n * Exact source backend identity.\n */\n sourceBackendId: string\n /**\n * Exact target backend identity.\n */\n targetBackendId: string\n /**\n * Parseable verification timestamp.\n */\n checkedAt: string\n /**\n * Nonempty matched in-scope record reports; host must establish exhaustive coverage.\n */\n records: readonly BackendMigrationVerification[]\n /**\n * Host declaration that verification passed; must be true for acceptance.\n */\n passed: boolean\n}\n\n/**\n * Host-reported routing switch retaining the original database for recovery.\n * \n * @see planBackendMigration for canonical integration usage.\n */\nexport interface BackendMigrationCutover {\n /**\n * Plan migration identity.\n */\n migrationId: string\n /**\n * Exact reviewed target backend.\n */\n targetBackendId: string\n /**\n * Nonnegative safe routing revision after cutover.\n */\n routingRevision: number\n /**\n * Parseable routing-switch timestamp.\n */\n cutoverAt: string\n /**\n * Must be true; destructive source cleanup is outside this contract.\n */\n sourceRetained: true\n}\n\n/**\n * Host-owned migration phases operating on real adapters and retained source storage.\n * \n * @see planBackendMigration for canonical integration usage.\n */\nexport interface BackendMigrationExecutor {\n /**\n * Provision/adopt the reviewed target and establish quiescence without deleting source data.\n * @param plan - Reviewed unmodified backend migration plan; host must preserve quiescence and source data.\n * @returns Resolves without a value after target preparation and required quiescence.\n * @throws Host adapter or callback failures reject the returned Promise; side effects may already be partially complete.\n \n * @example\n * ```typescript\n * import type { BackendMigrationExecutor, BackendMigrationPlan } from '@alneas/eaos-server/lifecycle-engine';\n * export async function prepareReviewed(executor: BackendMigrationExecutor, plan: BackendMigrationPlan) {\n * // The host approves exact targets and serializes migration writers.\n * await executor.prepare(plan);\n * }\n * ```\n */\n prepare(plan: BackendMigrationPlan): Promise<void>\n /**\n * Copy the scoped tenant/plugin data into the target and retain source state.\n * @param plan - Reviewed unmodified backend migration plan; host must preserve quiescence and source data.\n * @returns Resolves without a value after the scoped copy completes, with source retained.\n * @throws Host adapter or callback failures reject the returned Promise; side effects may already be partially complete.\n \n * @example\n * ```typescript\n * import type { BackendMigrationExecutor, BackendMigrationPlan } from '@alneas/eaos-server/lifecycle-engine';\n * export async function copyReviewed(executor: BackendMigrationExecutor, plan: BackendMigrationPlan) {\n * // The host approves exact targets and serializes migration writers.\n * await executor.copy(plan);\n * }\n * ```\n */\n copy(plan: BackendMigrationPlan): Promise<void>\n /**\n * Produce nonempty exhaustive host match evidence for the plan's scope.\n * @param plan - Reviewed unmodified backend migration plan; host must preserve quiescence and source data.\n * @returns The host verification report; caller must check it against the reviewed plan.\n * @throws Host adapter or callback failures reject the returned Promise; side effects may already be partially complete.\n \n * @example\n * ```typescript\n * import type { BackendMigrationExecutor, BackendMigrationPlan } from '@alneas/eaos-server/lifecycle-engine';\n * export async function verifyReviewed(executor: BackendMigrationExecutor, plan: BackendMigrationPlan) {\n * // The host approves exact targets and serializes migration writers.\n * return executor.verify(plan);\n * }\n * ```\n */\n verify(plan: BackendMigrationPlan): Promise<BackendMigrationVerificationReport>\n /**\n * Switch routing only after valid verification, retaining source and returning a cutover receipt.\n * @param plan - Reviewed unmodified backend migration plan; host must preserve quiescence and source data.\n * @param verification - Matching passed host verification report; establish complete copy coverage before cutover.\n * @returns A source-retaining routing cutover receipt after accepted verification.\n * @throws Host adapter or callback failures reject the returned Promise; side effects may already be partially complete.\n \n * @example\n * ```typescript\n * import type { BackendMigrationExecutor, BackendMigrationPlan, BackendMigrationVerificationReport } from '@alneas/eaos-server/lifecycle-engine';\n * export async function cutoverReviewed(executor: BackendMigrationExecutor, plan: BackendMigrationPlan, verification: BackendMigrationVerificationReport) {\n * // Supply current, successful evidence for this exact reviewed plan.\n * return executor.cutover(plan, verification);\n * }\n * ```\n */\n cutover(plan: BackendMigrationPlan, verification: BackendMigrationVerificationReport): Promise<BackendMigrationCutover>\n}\n\nfunction text(value: unknown, name: string, max = 256): string {\n if (typeof value !== 'string' || !value.trim() || value.length > max) throw new Error(`Invalid migration ${name}`)\n return value\n}\n\nfunction assertBackend(backend: BackendTarget, name: string): void {\n if (!backend || typeof backend !== 'object') throw new Error(`Invalid migration ${name}`)\n text(backend?.id, `${name} id`)\n text(backend?.databaseId, `${name} databaseId`)\n if (!['sqlite', 'postgres', 'oracle'].includes(backend.dialect) || !['shared', 'dedicated'].includes(backend.mode)) throw new Error(`Invalid migration ${name}`)\n if (backend.mode === 'dedicated' && !backend.tenantId) throw new Error(`Dedicated ${name} requires tenantId`)\n if (backend.mode === 'shared' && backend.tenantId !== undefined) throw new Error(`Shared ${name} cannot pin tenantId`)\n}\n\n/**\n * Creates a deterministic source-retaining migration plan without touching either database.\n * \n * Create a reviewable fleet/tenant data-migration plan without touching either backend.\n * @param request - Reviewed distinct physical source/target backends, concrete tenant scope, nonempty unique plugin IDs, timestamp and reason.\n * @returns A shallow-frozen plan with sorted cloned scopes/plugin IDs and five ordered phases.\n * @throws Error for malformed request, same source/target identity, invalid scope or dedicated-tenant mismatch.\n * \n * @remarks\n * Dedicated backend tenants must appear in explicit tenant scope. No executor, lock, provisioning, copy or cutover runs during planning; host must implement quiescence.\n * \n * @example\n * ```typescript\n * import { planBackendMigration } from '@alneas/eaos-server/lifecycle-engine/backend-migration';\n * const plan = planBackendMigration({ migrationId: 'move-1', source: { id: 'old', databaseId: 'db-old', dialect: 'sqlite', mode: 'shared' }, target: { id: 'new', databaseId: 'db-new', dialect: 'postgres', mode: 'shared' }, scope: { kind: 'tenants', tenantIds: ['sample'] }, pluginIds: ['reports'], requestedAt: '2026-01-01T00:00:00Z', reason: 'Reviewed backend move' });\n * ```\n */\nexport function planBackendMigration(request: BackendMigrationRequest): BackendMigrationPlan {\n text(request?.migrationId, 'migrationId')\n text(request?.reason, 'reason', 1024)\n if (!Number.isFinite(Date.parse(request.requestedAt))) throw new Error('Invalid migration requestedAt')\n assertBackend(request.source, 'source backend')\n assertBackend(request.target, 'target backend')\n if (request.source.id === request.target.id || request.source.databaseId === request.target.databaseId) throw new Error('Backend migration requires a different physical database')\n if (!Array.isArray(request.pluginIds) || request.pluginIds.length === 0 || new Set(request.pluginIds).size !== request.pluginIds.length || request.pluginIds.some(id => !/^[a-zA-Z0-9][a-zA-Z0-9_-]{0,127}$/.test(id))) throw new Error('Invalid migration pluginIds')\n if (!request.scope || typeof request.scope !== 'object' || !['all-tenants', 'tenants'].includes(request.scope.kind)) throw new Error('Invalid migration scope')\n if (request.scope.kind === 'tenants' && (!Array.isArray(request.scope.tenantIds) || request.scope.tenantIds.length === 0 || new Set(request.scope.tenantIds).size !== request.scope.tenantIds.length || request.scope.tenantIds.some(id => !/^\\S{1,256}$/.test(id)))) throw new Error('Invalid migration tenant scope')\n const scope = request.scope.kind === 'all-tenants' ? request.scope : { kind: 'tenants' as const, tenantIds: [...request.scope.tenantIds].sort() }\n const scopedTenants = scope.kind === 'tenants' ? scope.tenantIds : null\n if (request.source.mode === 'dedicated' && (!scopedTenants || !scopedTenants.includes(request.source.tenantId!))) throw new Error('Migration scope does not include the dedicated source tenant')\n if (request.target.mode === 'dedicated' && (!scopedTenants || !scopedTenants.includes(request.target.tenantId!))) throw new Error('Migration scope does not include the dedicated target tenant')\n const normalized = structuredClone({ ...request, pluginIds: [...request.pluginIds].sort(), scope })\n const body = { format: 1 as const, request: normalized, phases: ['prepare', 'copy', 'verify', 'cutover', 'retain-source'] as const, requiresQuiesce: true as const, retainSourceData: true as const, destructiveOperations: false as const }\n return Object.freeze({ ...body, id: lifecycleDigest(body) })\n}\n\n/**\n * Checks that a reported migration verification matches its plan and contains only matched in-scope records.\n * @param plan - Reviewed backend migration plan.\n * @param report - Host report claiming passed verification for the plan's source and target.\n * @returns The original report when accepted; it is neither cloned nor independently measured.\n * @throws Error for mismatched identities, invalid timestamp/revisions, out-of-scope records or unpassed/unmatched evidence.\n * \n * @remarks\n * Validates nonempty records and nonnegative revisions, but does not prove exhaustive tenant/plugin coverage or equal source/target revision numbers. The host owns verification completeness and truth.\n * \n * @example\n * ```typescript\n * import { assertBackendMigrationVerification, type BackendMigrationPlan, type BackendMigrationVerificationReport } from '@alneas/eaos-server/lifecycle-engine/backend-migration';\n * export function inspectVerification(plan: BackendMigrationPlan, report: BackendMigrationVerificationReport) { return assertBackendMigrationVerification(plan, report); }\n * ```\n */\nexport function assertBackendMigrationVerification(plan: BackendMigrationPlan, report: BackendMigrationVerificationReport): BackendMigrationVerificationReport {\n if (!report || report.migrationId !== plan.request.migrationId || report.sourceBackendId !== plan.request.source.id || report.targetBackendId !== plan.request.target.id || !Number.isFinite(Date.parse(report.checkedAt)) || report.passed !== true || !Array.isArray(report.records) || report.records.length === 0) throw new Error('Backend migration verification is incomplete')\n const tenants = plan.request.scope.kind === 'tenants' ? new Set(plan.request.scope.tenantIds) : null\n for (const record of report.records) {\n if (!record || typeof record.tenantId !== 'string' || (tenants && !tenants.has(record.tenantId)) || !plan.request.pluginIds.includes(record.pluginId) || !Number.isSafeInteger(record.sourceRevision) || record.sourceRevision < 0 || !Number.isSafeInteger(record.targetRevision) || record.targetRevision < 0 || record.matched !== true) throw new Error('Backend migration verification is incomplete')\n }\n return report\n}\n\n/**\n * Validates matching verification and a source-retaining cutover receipt for the target backend.\n * @param plan - Reviewed backend migration plan.\n * @param report - Passed host verification matching the plan.\n * @param cutover - Host routing receipt with nonnegative routing revision and parseable cutover timestamp.\n * @returns The original cutover object; no routing mutation occurs.\n * @throws Error for invalid verification, mismatched target/migration, missing source-retention claim or invalid revision/time.\n * \n * @remarks\n * This is evidence shape validation, not independent copy verification or authority to switch a tenant.\n * \n * @example\n * ```typescript\n * import { assertBackendMigrationCutover, type BackendMigrationPlan, type BackendMigrationVerificationReport, type BackendMigrationCutover } from '@alneas/eaos-server/lifecycle-engine/backend-migration';\n * export function inspectCutover(plan: BackendMigrationPlan, report: BackendMigrationVerificationReport, receipt: BackendMigrationCutover) { return assertBackendMigrationCutover(plan, report, receipt); }\n * ```\n */\nexport function assertBackendMigrationCutover(plan: BackendMigrationPlan, report: BackendMigrationVerificationReport, cutover: BackendMigrationCutover): BackendMigrationCutover {\n assertBackendMigrationVerification(plan, report)\n if (!cutover || cutover.migrationId !== plan.request.migrationId || cutover.targetBackendId !== plan.request.target.id || cutover.sourceRetained !== true || !Number.isSafeInteger(cutover.routingRevision) || cutover.routingRevision < 0 || !Number.isFinite(Date.parse(cutover.cutoverAt))) throw new Error('Backend migration cutover is invalid')\n return cutover\n}\n"],"mappings":"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","names":["lt","valid","satisfies","id","dataContractTables","resolveDataContracts","id","m","digest","version","valid","lt","resolveDataContracts","key","installed","satisfies"]}
|
|
1
|
+
{"version":3,"sources":["../src/lifecycle-engine/baseline.ts","../src/lifecycle-engine/index.ts","../package.json","../src/lifecycle-engine/backend-migration.ts"],"sourcesContent":["import { lt, valid, satisfies } from 'semver'\nimport { lifecycleDigest, resolveDataContracts, type DataContract, type LifecycleStore, type MigrationRecord } from './index'\n\n/**\n * Hash-bound replacement of exact historical database migrations by equivalent baseline DDL.\n * \n * @see createDataContractBaseline for canonical integration usage.\n */\nexport interface DataContractBaseline {\n /**\n * Baseline discriminator; currently 1.\n */\n format: 1\n /**\n * Canonical contract release whose fully applied history is replaced.\n */\n source: DataContract\n /**\n * Newer release retaining schema but using one database-scoped baseline migration.\n */\n target: DataContract\n /**\n * Ordered historical migration IDs, positions and checksums requiring exact ledger matches.\n */\n replaces: { \n /**\n * Original immutable migration ID replaced by the baseline.\n */\n id: string; \n /**\n * Original zero-based migration position.\n */\n position: number; \n /**\n * Canonical original migration definition digest.\n */\n checksum: string }[]\n /**\n * Canonical digest of format/source/target/replaces.\n */\n hash: string\n}\n/**\n * Builds a newer single-migration contract release and hashes the exact historical migrations it replaces.\n * \n * Final DDL comes from a schema compiler or an isolated database introspector, never concatenation.\n * @param source - Valid source contract with nonempty database-scoped migration history.\n * @param version - Valid semver strictly newer than source.version.\n * @param sql - Compiler/introspector-generated complete baseline DDL covering exactly the original dialect set.\n * @returns Source/target contract snapshots, replacement migration checksums and integrity hash.\n * @throws Error for nonnewer version, tenant-scoped/empty history, changed dialect set or invalid source/target contracts.\n * \n * @remarks\n * Read-only; the host must establish final DDL equivalence using a schema compiler or isolated introspector. SQL is not concatenated or executed here.\n * \n * @example\n * ```typescript\n * import { createDataContractBaseline, type DataContract } from '@alneas/eaos-server/lifecycle-engine';\n * export function reviewBaseline(source: DataContract, version: string, sql: DataContract['migrations'][number]['sql']) { return createDataContractBaseline(source, version, sql); }\n * ```\n */\nexport function createDataContractBaseline(source: DataContract, version: string, sql: DataContract['migrations'][number]['sql']): DataContractBaseline {\n if (!valid(version) || !lt(source.version, version) || !source.migrations.length || source.migrations.some(m => m.scope !== 'database')) throw Error('Baseline requires a newer contract version and database-scoped migrations')\n const dialects = [...new Set(source.migrations.flatMap(m => Object.keys(m.sql)))].sort()\n if (JSON.stringify(dialects) !== JSON.stringify(Object.keys(sql).sort())) throw Error('Baseline must preserve every declared dialect')\n const target: DataContract = { ...structuredClone(source), version, migrations: [{ id: `001_baseline_v${version.replaceAll('.', '_').replaceAll('-', '_')}`, scope: 'database', sql: structuredClone(sql) }] }\n resolveDataContracts([{ ...source, dependencies: undefined }], { [source.id]: source.version })\n resolveDataContracts([{ ...target, dependencies: undefined }], { [target.id]: version })\n const body = { format: 1 as const, source: structuredClone(source), target, replaces: source.migrations.map((m, position) => ({ id: m.id, position, checksum: lifecycleDigest(m) })) }\n return { ...body, hash: lifecycleDigest(body) }\n}\n/**\n * Replaces a completely applied exact contract history with its reviewed baseline ledger record without running DDL.\n * \n * Rebase only a completely applied exact history. This function never executes DDL.\n * @param store - Durable cross-process exclusive lifecycle store.\n * @param databaseId - Physical database ledger identity whose contract history is rebased.\n * @param baseline - Unmodified baseline created by createDataContractBaseline.\n * @param options - Expected ledger revision and optional all-instance quiesce callback, required when affected consumers are active.\n * @returns Baseline hash, next revision, count of replaced records and ddlExecuted=false.\n * @throws Rejects integrity mismatch, stale revision, partial/dirty history, incompatible installed consumer range, absent drain or propagated store/quiesce failures.\n * \n * @remarks\n * Runs under the store lock, archives old migration history and disables affected live consumers. Host drain happens before the final atomic state write; external drain may have occurred even if that write fails. No schema or data migration is executed.\n * \n * @example\n * ```typescript\n * import { rebaseDataContractBaseline, type DataContractBaseline, type LifecycleStore } from '@alneas/eaos-server/lifecycle-engine';\n * export function rebaseReviewed(store: LifecycleStore, databaseId: string, baseline: DataContractBaseline, options: Parameters<typeof rebaseDataContractBaseline>[3]) { return rebaseDataContractBaseline(store, databaseId, baseline, options); }\n * ```\n */\nexport async function rebaseDataContractBaseline(store: LifecycleStore, databaseId: string, baseline: DataContractBaseline, options: {\n \n /**\n * Exact current ledger revision reviewed by the caller; mismatch rejects before mutation.\n */\n expectedRevision: number\n /** Host drains all instances before disabling the affected live consumers. */\n quiesce?: (input: { \n /**\n * Exact physical database identity whose live consumers must drain.\n */\n databaseId: string; \n /**\n * Distinct affected feature IDs consuming the rebased contract.\n */\n pluginIds: string[] }) => Promise<void>\n}) {\n const { hash, ...body } = baseline\n if (hash !== lifecycleDigest(body) || hash !== createDataContractBaseline(baseline.source, baseline.target.version, baseline.target.migrations[0]?.sql ?? {}).hash) throw Error('Baseline integrity differs')\n return store.withLock(async writer => {\n const state = await writer.read()\n if (state.revision !== options.expectedRevision) throw Error('Baseline plan is stale')\n const key = JSON.stringify([databaseId, baseline.source.id]), installed = state.dataContracts?.[key]\n if (!installed || installed.status !== 'installed' || installed.digest !== lifecycleDigest(baseline.source)) throw Error('Baseline source contract is not completely installed')\n const identity = baseline.source.migrationIdentity ?? `data-${baseline.source.id}`\n const history = Object.entries(state.migrations).filter(([, r]) => r.databaseId === databaseId && r.pluginId === identity)\n if (history.length !== baseline.replaces.length || baseline.replaces.some(replaced => !history.some(([, r]) => r.migrationId === replaced.id && r.position === replaced.position && r.checksum === replaced.checksum && r.tenantId === null && r.status === 'applied'))) throw Error('Baseline history is partial, changed or dirty')\n for (const [key, installed] of Object.entries(state.installations)) {\n const range = installed.release.schemaDependencies?.[baseline.source.id]\n if (state.backends[JSON.parse(key)[0]]?.databaseId === databaseId && range && !satisfies(baseline.target.version, range)) throw Error('Baseline violates an installed plugin contract range')\n }\n const live = Object.values(state.activations).filter(a => a.enabled && state.backends[a.backendId]?.databaseId === databaseId && state.installations[JSON.stringify([a.backendId, a.pluginId])]?.release.schemaDependencies?.[baseline.source.id])\n if (live.length && !options.quiesce) throw Error('Baseline requires all-instance drain')\n if (live.length) await options.quiesce!({ databaseId, pluginIds: [...new Set(live.map(a => a.pluginId))] })\n for (const a of live) a.enabled = false\n state.baselineHistory ??= {}\n const archiveKey = JSON.stringify([databaseId, identity, hash])\n if (state.baselineHistory[archiveKey]) throw Error('Baseline history already exists')\n state.baselineHistory[archiveKey] = { hash, source: baseline.source, migrations: Object.fromEntries(history) }\n for (const [key] of history) delete state.migrations[key]\n const m = baseline.target.migrations[0]\n state.migrations[JSON.stringify([databaseId, identity, m.id, '*'])] = { databaseId, pluginId: identity, migrationId: m.id, position: 0, tenantId: null, checksum: lifecycleDigest(m), status: 'applied' }\n state.dataContracts![key] = { contract: structuredClone(baseline.target), digest: lifecycleDigest(baseline.target), status: 'installed' }\n state.revision++\n await writer.write(state)\n return { baselineHash: hash, revision: state.revision, rebased: history.length, ddlExecuted: false as const }\n })\n}\n","import { dataContractTables, resolveDataContracts, type DataContract, type DataContractCatalog } from '@alneas/eaos-core/contracts/data-contracts'\nimport { createHash } from 'node:crypto'\nimport { satisfies, valid, validRange, lt } from 'semver'\nimport { version as packageVersion } from '../../package.json'\nimport type { BackendMigrationCutover, BackendMigrationPlan, BackendMigrationVerificationReport } from './backend-migration'\n/**\n * Installed server package version used as the default lifecycle compatibility version.\n * \n * @see PluginLifecycle for canonical integration usage.\n */\nexport const FRAMEWORK_VERSION = packageVersion\n/**\n * Supported SQL dialects used to select reviewed migration statements.\n * \n * @see PluginLifecycle for canonical integration usage.\n */\nexport type Dialect = 'sqlite' | 'oracle' | 'postgres'\nexport * from './baseline'\n/**\n * Opaque physical database placement and shared/dedicated tenant scope.\n * \n * @see PluginLifecycle for canonical integration usage.\n */\nexport interface BackendTarget {\n /**\n * Stable execution backend ID; lifecycle plans reject identity changes under an existing ID.\n */\n id: string;\n /**\n * Opaque physical database identity shared by aliases of the same database; never a DSN.\n */\n databaseId: string;\n /**\n * SQL dialect required by this database and migration history.\n */\n dialect: Dialect;\n /**\n * Shared permits tenant isolation within one database; dedicated binds one tenant.\n */\n mode: 'shared' | 'dedicated';\n /**\n * Required concrete tenant for dedicated mode and forbidden for shared mode.\n */\n tenantId?: string }\n/**\n * Immutable reviewed migration statements scoped to a physical database or one tenant.\n * \n * @see PluginLifecycle for canonical integration usage.\n */\nexport interface PluginMigration {\n /**\n * Stable unique migration ID whose applied definition must never be rewritten.\n */\n id: string;\n /**\n * Database runs once per physical database; tenant runs once per tenant.\n */\n scope: 'database' | 'tenant';\n /**\n * Dialect-to-ordered-statements map; the target dialect must have nonempty statements.\n */\n sql: Partial<Record<Dialect, string[]>> }\n/**\n * Trusted release definition with feature dependencies, schema requirements and immutable migrations.\n * \n * @see PluginLifecycle for canonical integration usage.\n */\nexport interface LifecyclePlugin {\n /**\n * Registered feature identifier, up to 128 letters/digits/underscore/hyphen characters starting alphanumeric.\n */\n id: string;\n /**\n * Valid semantic release version; changed contents require a version bump.\n */\n version: string;\n /**\n * Valid semver range for compatible framework versions.\n */\n framework: string\n /**\n * Optional feature ID to semver range dependencies installed/enabled as a closure.\n */\n dependencies?: Record<string, string>\n /**\n * Optional canonical data contract ranges; never installs or enables feature plugins.\n * \n * Storage dependencies do not install or enable a feature plugin.\n */\n schemaDependencies?: Record<string, string>\n /**\n * Optional canonical releases supplied by a data package; duplicate IDs must agree exactly.\n * \n * Canonical contract releases supplied by the data package, not inline table copies.\n */\n schemaContracts?: DataContract[]\n /**\n * Append-only reviewed plugin migrations; contract-backed plugins must put DDL in data contracts instead.\n * \n * Immutable, reviewed migrations generated from the plugin's schema; never rewrite applied IDs.\n */\n migrations: PluginMigration[]\n /**\n * Optional nonsecret declarative host requirements; absence causes no infrastructure work.\n * \n * Declarative, host-defined resource requirements. No secrets. Absence means no infrastructure changes.\n */\n infrastructure?: Record<string, unknown>\n}\n/**\n * Lifecycle change to installation or tenant activation; disable/uninstall retain business data.\n * \n * @see PluginLifecycle for canonical integration usage.\n */\nexport type Operation = 'install' | 'update' | 'enable' | 'disable' | 'uninstall'\n/**\n * Concrete lifecycle operation scoped to one registered backend and verified tenant.\n * \n * @see PluginLifecycle for canonical integration usage.\n */\nexport interface LifecycleRequest {\n /**\n * Requested install/update/enable/disable/uninstall transition.\n */\n operation: Operation;\n /**\n * Registered plugin ID, or bundle ID for bundle planning.\n */\n pluginId: string;\n /**\n * Registered execution backend ID.\n */\n backendId: string;\n /**\n * Verified concrete tenant; must match dedicated backend scope.\n */\n tenantId: string }\n/**\n * Durable per-database/tenant migration progress and immutable definition checksum.\n * \n * @see PluginLifecycle for canonical integration usage.\n */\nexport interface MigrationRecord {\n /**\n * Physical database on which the migration executes.\n */\n databaseId: string;\n /**\n * Plugin or canonical data-contract migration identity.\n */\n pluginId: string;\n /**\n * Immutable migration definition ID.\n */\n migrationId: string;\n /**\n * Zero-based position in the append-only migration history.\n */\n position: number;\n /**\n * Concrete tenant for tenant-scoped work, or null for database scope.\n */\n tenantId: string | null;\n /**\n * Canonical definition digest used to detect rewritten applied SQL.\n */\n checksum: string;\n /**\n * Running/applied/failed progress; running and failed require reconciliation before planning further changes.\n */\n status: 'running' | 'applied' | 'failed' }\n/**\n * Registered release snapshot and progress stored for one backend/plugin.\n * \n * @see PluginLifecycle for canonical integration usage.\n */\nexport interface Installation {\n /**\n * Copied trusted plugin release installed on this backend.\n */\n release: LifecyclePlugin;\n /**\n * Canonical digest of the release snapshot.\n */\n digest: string;\n /**\n * Installing/installed/failed progress; noninstalled records require reconciliation.\n */\n status: 'installing' | 'installed' | 'failed' }\n/**\n * Durable platform tenant metadata independent of business schemas.\n * \n * @see PluginLifecycle for canonical integration usage.\n */\nexport interface LifecyclePlatformTenant {\n /**\n * Stable concrete tenant ID.\n */\n id: string;\n /**\n * Public tenant display name.\n */\n name: string;\n /**\n * Whether platform tenant admission is enabled; membership remains host-owned.\n */\n active: boolean;\n /**\n * Configured tenant lookup domains; domain mapping alone never proves membership.\n */\n domains: readonly string[];\n /**\n * Tenant creation timestamp.\n */\n createdAt: string;\n /**\n * Latest metadata update timestamp.\n */\n updatedAt: string }\n/**\n * Durable tenant-to-backend routing assignment with optimistic routing revision.\n * \n * @see PluginLifecycle for canonical integration usage.\n */\nexport interface LifecyclePlatformPlacement {\n /**\n * Verified tenant whose traffic is routed.\n */\n tenantId: string;\n /**\n * Opaque configured backend receiving traffic.\n */\n backendId: string;\n /**\n * Nonnegative revision used to track routing changes.\n */\n routingRevision: number;\n /**\n * Timestamp of the recorded routing switch.\n */\n changedAt: string }\n/**\n * Nonsecret descriptive metadata for an existing backend.\n * \n * @see PluginLifecycle for canonical integration usage.\n */\nexport interface LifecyclePlatformBackendMetadata {\n /**\n * Optional public display label.\n */\n label?: string;\n /**\n * Optional provider descriptor; never credentials or DSNs.\n */\n provider?: string;\n /**\n * Optional declared host capability names, not permission grants.\n */\n capabilities?: readonly string[] }\n/**\n * Persisted migration progress including uncertainty, failure, reconciliation and rollback states.\n * \n * @see PluginLifecycle for canonical integration usage.\n */\nexport type LifecyclePlatformMigrationStatus = 'planned' | 'running' | 'verified' | 'cutover' | 'failed' | 'reconciling' | 'rolled-back'\n/**\n * Durable migration execution, verification and reconciliation evidence.\n * \n * @see PluginLifecycle for canonical integration usage.\n */\nexport interface LifecyclePlatformMigrationRecord {\n /**\n * Current progress; reconciling represents uncertain execution outcomes.\n */\n status: LifecyclePlatformMigrationStatus\n /**\n * Optional identity claiming the host migration execution.\n */\n executionId?: string\n /**\n * Optional host-reported verification matching the migration plan.\n */\n verification?: BackendMigrationVerificationReport\n /**\n * Optional source-retaining cutover receipt.\n */\n cutover?: BackendMigrationCutover\n /**\n * Optional failure message and occurrence timestamp; exclude secrets.\n */\n error?: { \n /**\n * Nonsecret failure description retained for operator reconciliation.\n */\n message: string; \n /**\n * Timestamp at which the error was recorded.\n */\n occurredAt: string }\n /**\n * Timestamp of the latest migration-state change.\n */\n updatedAt: string\n /**\n * Optional original migration ID when this is a rollback execution.\n */\n rollbackOf?: string\n /**\n * Optional reviewed reverse plan associated with this migration.\n */\n rollbackPlanId?: string\n}\n/**\n * Platform-owned tenant, backend and migration control maps stored with the lifecycle ledger.\n * \n * @see PluginLifecycle for canonical integration usage.\n */\nexport interface LifecyclePlatformState {\n /**\n * Tenant records indexed by tenant ID.\n */\n tenants: Record<string, LifecyclePlatformTenant>\n /**\n * Current routing assignments indexed by tenant ID.\n */\n placements: Record<string, LifecyclePlatformPlacement>\n /**\n * Nonsecret backend labels/provider capabilities indexed by backend ID.\n */\n backendMetadata: Record<string, LifecyclePlatformBackendMetadata>\n /**\n * Reviewed backend migration plans indexed by migration ID.\n */\n migrationPlans: Record<string, BackendMigrationPlan>\n /**\n * Execution/reconciliation records indexed by migration ID.\n */\n migrationRecords: Record<string, LifecyclePlatformMigrationRecord>\n}\n/**\n * Versioned durable control ledger for plugin readiness, schema history and platform placement.\n * \n * @see PluginLifecycle for canonical integration usage.\n */\nexport interface LifecycleState {\n /**\n * Optional archived exact histories replaced by reviewed baselines.\n */\n baselineHistory?: Record<string, { \n /**\n * Exact archived baseline integrity hash.\n */\n hash: string; \n /**\n * Original canonical contract release retained for historical evidence.\n */\n source: DataContract; \n /**\n * Archived exact applied migration receipts.\n */\n migrations: Record<string, MigrationRecord> }>\n /**\n * Persistent ledger discriminator; currently 1.\n */\n format: 1;\n /**\n * Nonnegative safe integer incremented on persisted lifecycle changes.\n */\n revision: number\n /**\n * Opaque backend target definitions indexed by backend ID.\n */\n backends: Record<string, BackendTarget>\n /**\n * Release snapshots indexed by JSON [backendId, pluginId].\n */\n installations: Record<string, Installation>\n /**\n * Requested tenant activation records indexed by JSON [backendId, tenantId, pluginId]; effective readiness is checked separately.\n */\n activations: Record<string, { \n /**\n * Registered execution backend owning this activation.\n */\n backendId: string; \n /**\n * Concrete verified tenant owning this activation.\n */\n tenantId: string; \n /**\n * Registered feature ID requested for activation.\n */\n pluginId: string; \n /**\n * Canonical release or infrastructure definition digest.\n */\n digest: string; \n /**\n * Requested activation flag; effective readiness also requires matching installed digests and dependencies.\n */\n enabled: boolean }>\n /**\n * Progress indexed by JSON [databaseId, migrationIdentity, migrationId, tenantId-or-*].\n */\n migrations: Record<string, MigrationRecord>\n /**\n * Infrastructure digests/progress indexed by JSON [backendId, pluginId].\n */\n infrastructure: Record<string, { \n /**\n * Canonical release or infrastructure definition digest.\n */\n digest: string; \n /**\n * Persisted installing/installed/failed or running/applied/failed progress, according to this ledger map.\n */\n status: 'running' | 'applied' | 'failed' }>\n /**\n * Tenant/control-plane metadata and backend migration evidence.\n */\n platform: LifecyclePlatformState\n /**\n * Optional canonical contract installation records indexed by JSON [databaseId, contractId].\n */\n dataContracts?: Record<string, { \n /**\n * Canonical schema contract release bound by its stored digest.\n */\n contract: DataContract; \n /**\n * Canonical release or infrastructure definition digest.\n */\n digest: string; \n /**\n * Persisted installing/installed/failed or running/applied/failed progress, according to this ledger map.\n */\n status: 'installing' | 'installed' | 'failed' }>\n}\n/**\n * Atomic lifecycle snapshot access made available inside the host's exclusive lock.\n * \n * @see PluginLifecycle for canonical integration usage.\n */\nexport interface LifecycleWriter {\n /**\n * Read the currently committed ledger snapshot; must not expose uncommitted writes.\n * @returns The currently committed atomic ledger snapshot.\n * @throws Host adapter or callback failures reject the returned Promise; side effects may already be partially complete.\n \n * @example\n * ```typescript\n * import type { LifecycleStore } from '@alneas/eaos-server/lifecycle-engine';\n * export async function readLocked(store: LifecycleStore) {\n * return store.withLock(async writer => writer.read());\n * }\n * ```\n */\n read(): Promise<LifecycleState>;\n /**\n * Atomically persist the complete next snapshot; resolve only after durable completion.\n * @param state - Complete next ledger snapshot with updated revision and control metadata.\n * @returns Resolves without a value after the complete snapshot is durably committed.\n * @throws Host adapter or callback failures reject the returned Promise; side effects may already be partially complete.\n \n * @example\n * ```typescript\n * import type { LifecycleStore } from '@alneas/eaos-server/lifecycle-engine';\n * export async function persistReviewedRevision(store: LifecycleStore) {\n * await store.withLock(async writer => {\n * const state = await writer.read();\n * // Domain changes belong in the same reviewed writer callback.\n * state.revision += 1;\n * await writer.write(state);\n * });\n * }\n * ```\n */\n write(state: LifecycleState): Promise<void> }\n/**\n * Durable lifecycle reads and cross-process exclusive writer coordination.\n * \n * \n * withLock must exclude every other writer, across processes. Reads must observe atomic committed snapshots.\n * @see PluginLifecycle for canonical integration usage.\n */\nexport interface LifecycleStore extends Pick<LifecycleWriter, 'read'> {\n /**\n * Exclude every competing writer across processes and hold the lock until the async callback settles; release on success or failure.\n * @param fn - Async work invoked only while holding exclusive writer ownership; receives atomic read/write capabilities.\n * @typeParam T - Result resolved by the exclusive-lock callback.\n * @returns The callback result after its lock is released; the lock is also released on failure.\n * @throws Host adapter or callback failures reject the returned Promise; side effects may already be partially complete.\n \n * @example\n * ```typescript\n * import type { LifecycleStore } from '@alneas/eaos-server/lifecycle-engine';\n * export async function snapshot(store: LifecycleStore) {\n * return store.withLock(async writer => writer.read());\n * }\n * ```\n */\n withLock<T>(fn: (writer: LifecycleWriter) => Promise<T>): Promise<T> }\n/**\n * Planned migration ledger identity and ordered SQL to execute on one physical target.\n * \n * @see PluginLifecycle for canonical integration usage.\n */\nexport interface MigrationStep {\n /**\n * Exact ledger map key for this migration and scope.\n */\n key: string;\n /**\n * Initial running migration receipt with immutable checksum.\n */\n record: MigrationRecord;\n /**\n * Reviewed target-dialect SQL executed in order by the host migrate adapter.\n */\n statements: string[] }\n/**\n * Planned host infrastructure change bound to the release and backend digest.\n * \n * @see PluginLifecycle for canonical integration usage.\n */\nexport interface InfrastructureStep {\n /**\n * Infrastructure ledger key for backend/plugin.\n */\n key: string;\n /**\n * Canonical digest binding backend and plugin infrastructure configuration.\n */\n digest: string;\n /**\n * Trusted plugin release declaring infrastructure requirements.\n */\n plugin: LifecyclePlugin;\n /**\n * Exact target whose resources are previewed/applied.\n */\n backend: BackendTarget }\n/**\n * Reviewable hash-bound lifecycle transition generated against one ledger revision.\n * \n * @see PluginLifecycle for canonical integration usage.\n */\nexport interface LifecyclePlan {\n /**\n * Plan discriminator; currently 1.\n */\n format: 1;\n /**\n * Canonical SHA-256 hash of all plan body fields.\n */\n id: string;\n /**\n * Ledger revision observed during planning; apply rejects stale plans.\n */\n revision: number;\n /**\n * Framework compatibility version used to resolve the plan.\n */\n frameworkVersion: string;\n /**\n * Original scoped operation request.\n */\n request: LifecycleRequest;\n /**\n * Snapshot of the exact immutable backend identity.\n */\n backend: BackendTarget\n /**\n * Optional dependency-resolved canonical data contracts and table ownership.\n */\n dataCatalog?: DataContractCatalog\n /**\n * Dependency-ordered trusted feature releases involved in the transition.\n */\n plugins: LifecyclePlugin[];\n /**\n * Ordered migration steps not already applied with matching checksums.\n */\n migrations: MigrationStep[];\n /**\n * Planned host infrastructure changes requiring the configured executor.\n */\n infrastructure: InfrastructureStep[]\n /**\n * Activation map keys disabled before disruptive changes.\n */\n deactivate: string[];\n /**\n * Configured executor identity, or null when none exists.\n */\n infrastructureProvider: string | null;\n /**\n * Always true; lifecycle uninstall never drops business data.\n */\n retainData: true\n}\n/**\n * Host-provided trusted release catalogs, durable lifecycle storage and side-effect adapters.\n * \n * @see PluginLifecycle for canonical integration usage.\n */\nexport interface LifecycleProject {\n /**\n * Cross-process locked atomic durable lifecycle store.\n */\n store: LifecycleStore;\n /**\n * Trusted configured backend catalog; existing physical identities are immutable.\n */\n backends: BackendTarget[];\n /**\n * Trusted registered plugin releases; registration alone grants no tenant activation.\n */\n plugins: LifecyclePlugin[]\n /**\n * Optional canonical schema contract releases, also collected from plugin schemaContracts.\n * \n */\n dataContracts?: readonly DataContract[]\n /**\n * Optional host aliases mapping bundle IDs to ordered registered feature IDs.\n */\n bundles?: Record<string, readonly string[]>\n /**\n * Execute one reviewed migration step on the exact backend; reject failures so reconciliation state is recorded.\n * @param step - Exact planned infrastructure step and target digest; do not reinterpret unreviewed settings.\n * @param backend - Already-provisioned opaque backend declaration; never a connection string or credentials.\n * @returns Resolves without a value after the reviewed host side effect completes.\n * @throws Host adapter or callback failures reject the returned Promise; side effects may already be partially complete.\n */\n migrate: (step: MigrationStep, backend: BackendTarget) => Promise<void>\n /**\n * Optional all-instance admission stop and active-work drain; required before upgrades affecting enabled activations.\n * \n * Stop admission and drain existing work on ALL affected backend instances before upgrades.\n * @param activations - Host operation input bound to the scope described by this member.\n * @returns Resolves without a value after the reviewed host side effect completes.\n * @throws Host adapter or callback failures reject the returned Promise; side effects may already be partially complete.\n */\n quiesce?: (activations: LifecycleState['activations'][string][]) => Promise<void>\n /**\n * Optional named host preview/apply capability; no credentials belong in declarative plugin settings.\n */\n infrastructure?: { \n /**\n * Stable nonsecret infrastructure-provider identity bound into reviewed plans.\n */\n identity: string; \n /**\n * Preview one exact infrastructure step; host must not claim application completion from preview.\n * @param step - Exact reviewed infrastructure step for the configured backend.\n * @returns Host preview information; no apply result is implied.\n * @throws Rejects host adapter failures; effects may already have partially completed.\n \n * @example\n * ```typescript\n * import type { LifecycleProject, InfrastructureStep } from '@alneas/eaos-server/lifecycle-engine';\n * export async function previewInfrastructure(project: LifecycleProject, step: InfrastructureStep) {\n * if (!project.infrastructure) throw new Error(\"Host infrastructure port required\");\n * return project.infrastructure.preview(step);\n * }\n * ```\n */\n preview(step: InfrastructureStep): Promise<unknown>; \n /**\n * Apply one reviewed infrastructure step; errors leave reconciliation state and may follow partial external success.\n * @param step - Exact reviewed infrastructure step for the configured backend.\n * @returns Resolves without a value after host application completes.\n * @throws Rejects host adapter failures; effects may already have partially completed.\n \n * @example\n * ```typescript\n * import type { LifecycleProject, InfrastructureStep } from '@alneas/eaos-server/lifecycle-engine';\n * export async function applyInfrastructure(project: LifecycleProject, step: InfrastructureStep) {\n * if (!project.infrastructure) throw new Error(\"Host infrastructure port required\");\n * await project.infrastructure.apply(step);\n * }\n * ```\n */\n apply(step: InfrastructureStep): Promise<void> }\n}\n/**\n * One registered or historical plugin/backend pair with requested and effective tenant readiness.\n * \n * @see PluginLifecycle for canonical integration usage.\n */\nexport interface LifecycleInventoryEntry {\n /**\n * Registered or historically recorded plugin ID.\n */\n pluginId: string\n /**\n * Backend associated with the entry, or null when no backend is known.\n */\n backendId: string | null\n /**\n * Whether this backend remains in the trusted runtime catalog.\n */\n backendConfigured: boolean\n /**\n * Current registered code version, or null for orphaned history.\n */\n registeredVersion: string | null\n /**\n * Stored installation version, or null before installation.\n */\n installedVersion: string | null\n /**\n * Stored progress or not-installed.\n */\n installationStatus: Installation['status'] | 'not-installed'\n /**\n * Whether stored digest matches registered code, or null without installation.\n */\n releaseMatches: boolean | null\n /**\n * Tenant requestedEnabled flags and effective enabled readiness results.\n */\n tenants: { \n /**\n * Concrete tenant whose activation is inspected.\n */\n tenantId: string; \n /**\n * Stored requested activation flag without readiness guarantees.\n */\n requestedEnabled: boolean; \n /**\n * Effective lifecycle readiness for the registered release and dependency closure.\n */\n enabled: boolean }[]\n}\n/**\n * Read-only revision-bound plugin inventory including code-only and orphaned entries.\n * \n * @see PluginLifecycle for canonical integration usage.\n */\nexport interface LifecycleInventory {\n /**\n * Inventory discriminator; currently 1.\n */\n format: 1\n /**\n * Ledger snapshot revision inspected.\n */\n revision: number\n /**\n * Framework compatibility version used for readiness.\n */\n frameworkVersion: string\n /**\n * Deterministically ordered plugin/backend inventory entries, possibly empty.\n */\n plugins: LifecycleInventoryEntry[]\n}\n/**\n * Reviewable ordered collection of member plans with projected sequential ledger revisions.\n * \n * @see PluginLifecycle for canonical integration usage.\n */\nexport interface LifecycleBundlePlan {\n /**\n * Bundle discriminator; currently 1.\n */\n format: 1;\n /**\n * Canonical digest of bundle identity, operation and member plans.\n */\n id: string;\n /**\n * Registered host bundle alias.\n */\n bundleId: string;\n /**\n * Transition applied to every bundle member.\n */\n operation: Operation;\n /**\n * Dependency-compatible member order; reversed for disable/uninstall.\n */\n plans: LifecyclePlan[] }\nexport * from './backend-migration'\nexport * from '@alneas/eaos-core/contracts/data-contracts'\nexport { dataContractTables, resolveDataContracts, assertDataContractBinding, collectSchemaMigrations, createJsonDocumentAssertion, assertJsonDocumentContracts } from '@alneas/eaos-core/contracts/data-contracts'\n/**\n * Creates independent empty platform tenant, placement and migration maps.\n * @returns A new mutable platform-state object.\n * \n * @example\n * ```typescript\n * import { emptyLifecyclePlatformState } from '@alneas/eaos-server/lifecycle-engine';\n * const platform = emptyLifecyclePlatformState();\n * ```\n */\nexport const emptyLifecyclePlatformState = (): LifecyclePlatformState => ({ tenants: {}, placements: {}, backendMetadata: {}, migrationPlans: {}, migrationRecords: {} })\n/**\n * Creates an independent empty version-1 ledger with revision zero and platform state.\n * @returns A new mutable LifecycleState with empty maps; no persistence is performed.\n * \n * @example\n * ```typescript\n * import { emptyLifecycleState } from '@alneas/eaos-server/lifecycle-engine';\n * const state = emptyLifecycleState();\n * ```\n */\nexport const emptyLifecycleState = (): LifecycleState => ({ format: 1, revision: 0, backends: {}, installations: {}, activations: {}, migrations: {}, infrastructure: {}, platform: emptyLifecyclePlatformState() })\n/**\n * Clones a historical ledger snapshot and fills missing platform maps without rewriting storage.\n * \n * Add fields introduced after the original snapshot format without rewriting old control rows on read.\n * @param input - Historical state snapshot to normalize.\n * @returns A structured clone with a complete platform object; unrelated state validation remains the caller's responsibility.\n * @throws Error for nonobject input or malformed platform/maps; structuredClone errors propagate.\n * \n * @example\n * ```typescript\n * import { emptyLifecycleState, normalizeLifecycleState } from '@alneas/eaos-server/lifecycle-engine';\n * const state = normalizeLifecycleState(emptyLifecycleState());\n * ```\n */\nexport function normalizeLifecycleState(input: LifecycleState): LifecycleState {\n if (!input || typeof input !== 'object') throw new Error('Invalid lifecycle state')\n const state = structuredClone(input) as LifecycleState\n if (state.platform === undefined) state.platform = emptyLifecyclePlatformState()\n if (!state.platform || typeof state.platform !== 'object' || Array.isArray(state.platform)) throw new Error('Invalid lifecycle platform state')\n for (const field of ['tenants', 'placements', 'backendMetadata', 'migrationPlans', 'migrationRecords'] as const) {\n if (state.platform[field] === undefined) state.platform[field] = {}\n if (!state.platform[field] || typeof state.platform[field] !== 'object' || Array.isArray(state.platform[field])) throw new Error(`Invalid lifecycle platform ${field}`)\n }\n return state\n}\n/**\n * Serializes JSON-compatible lifecycle values with recursively sorted object keys.\n * @param value - JSON-serializable primitives, arrays or plain/null-prototype objects; avoid cycles and nonfinite numbers.\n * @returns Deterministic JSON text; array order is preserved.\n * @throws Error for unsupported values/prototypes, JSON serialization failure or recursive cycles.\n * \n * @remarks\n * Uses JSON.stringify primitive semantics, including null for nonfinite numbers. It does not accept undefined/function/symbol values or class instances. Cyclic graphs are unsupported.\n * \n * @example\n * ```typescript\n * import { canonical } from '@alneas/eaos-server/lifecycle-engine';\n * const serialized = canonical({ b: [2, 1], a: true });\n * ```\n */\nexport function canonical(value: unknown): string {\n if (value === null || typeof value !== 'object') {\n const result = JSON.stringify(value)\n if (result === undefined) throw new Error('Lifecycle configuration must be JSON serializable')\n return result\n }\n if (Array.isArray(value)) return '[' + value.map(canonical).join(',') + ']'\n if (Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null) throw new Error('Lifecycle configuration must contain plain objects')\n return '{' + Object.keys(value).sort().map(k => JSON.stringify(k) + ':' + canonical((value as any)[k])).join(',') + '}'\n}\n/**\n * Computes a lowercase SHA-256 digest of the canonical lifecycle JSON representation.\n * @param value - Supported canonical JSON lifecycle configuration.\n * @returns A 64-character lowercase hexadecimal digest.\n * @throws Propagates canonical serialization errors for unsupported values.\n * \n * @remarks\n * Requires Node crypto; the digest proves content identity, not authorization or authenticity.\n * \n * @example\n * ```typescript\n * import { lifecycleDigest } from '@alneas/eaos-server/lifecycle-engine';\n * const digest = lifecycleDigest({ pluginId: 'reports', version: '1.0.0' });\n * ```\n */\nexport const lifecycleDigest = (value: unknown): string => createHash('sha256').update(canonical(value)).digest('hex')\nconst key = (...parts: string[]) => JSON.stringify(parts)\nfunction id(value: string): void { if (!/^[a-zA-Z0-9][a-zA-Z0-9_-]{0,127}$/.test(value)) throw new Error('Invalid lifecycle identifier') }\nfunction assertState(s: LifecycleState): void {\n if (s?.format !== 1 || !Number.isSafeInteger(s.revision) || s.revision < 0 || !s.backends || !s.installations || !s.activations || !s.migrations || !s.infrastructure) throw new Error('Invalid lifecycle state')\n if (s.dataContracts !== undefined) {\n if (!s.dataContracts || typeof s.dataContracts !== 'object' || Array.isArray(s.dataContracts)) throw new Error('Invalid data contract state')\n for (const [recordKey, record] of Object.entries(s.dataContracts)) {\n const parts = JSON.parse(recordKey)\n if (!Array.isArray(parts) || parts.length !== 2 || parts[1] !== record.contract?.id || record.digest !== lifecycleDigest(record.contract) || !['installing', 'installed', 'failed'].includes(record.status)) throw new Error('Invalid data contract state record')\n }\n }\n}\n/**\n * Plans and applies checksum-bound plugin/schema changes against an exclusively locked host ledger.\n * \n * @remarks\n * Server runtime uses Node crypto and semver. The host provides durable cross-process locking, tenant authorization, SQL migration execution and any infrastructure/quiesce adapters. Installation never implies tenant enablement; disable/uninstall retain data. Migration/infrastructure failures persist reconciliation state, and DDL is not rolled back automatically.\n * \n * @example\n * ```typescript\n * import { PluginLifecycle, type LifecycleProject } from '@alneas/eaos-server/lifecycle-engine';\n * export function connectLifecycle(project: LifecycleProject) { return new PluginLifecycle(project); }\n * ```\n */\nexport class PluginLifecycle {\n private readonly plugins: Map<string, LifecyclePlugin>\n private readonly backends: Map<string, BackendTarget>\n private readonly contracts: DataContract[]\n /**\n * Validates and snapshots the registered plugin, backend, contract and bundle catalogs.\n * @param project - Host lifecycle storage, trusted catalogs and execution adapters.\n * @param frameworkVersion - Valid semver framework version; defaults to the installed package version.\n * @throws Error for invalid/duplicate IDs, versions, migrations, conflicting schemas, unsupported backend configuration or unsatisfied contract dependencies.\n * \n * @example\n * ```typescript\n * import { PluginLifecycle, type LifecycleProject } from '@alneas/eaos-server/lifecycle-engine';\n * export function connectLifecycle(project: LifecycleProject) { return new PluginLifecycle(project); }\n * ```\n */\n constructor(private readonly project: LifecycleProject, readonly frameworkVersion = FRAMEWORK_VERSION) {\n if (!valid(frameworkVersion)) throw new Error('Invalid framework version')\n const plugins = JSON.parse(canonical(project.plugins)) as LifecyclePlugin[]\n const backends = JSON.parse(canonical(project.backends)) as BackendTarget[]\n this.plugins = new Map(); this.backends = new Map()\n for (const p of plugins) {\n id(p.id)\n if (this.plugins.has(p.id) || !valid(p.version) || !validRange(p.framework)) throw new Error('Invalid or duplicate plugin release')\n if ((project.dataContracts !== undefined || Object.keys(p.schemaDependencies ?? {}).length) && p.migrations.length) throw new Error(`Contract-backed plugin must put DDL in data contracts: ${p.id}`)\n const migrations = new Set<string>()\n for (const m of p.migrations) {\n id(m.id)\n if (migrations.has(m.id) || !['database', 'tenant'].includes(m.scope)) throw new Error('Invalid or duplicate migration')\n for (const sql of Object.values(m.sql)) if (!Array.isArray(sql) || !sql.length || sql.some(s => typeof s !== 'string' || !s.trim())) throw new Error('Invalid migration SQL')\n migrations.add(m.id)\n }\n const release = { ...p }; delete release.schemaContracts\n this.plugins.set(p.id, release)\n }\n const contracts = new Map<string, DataContract>()\n for (const contract of [...(project.dataContracts ?? []), ...plugins.flatMap(p => p.schemaContracts ?? [])]) {\n const previous = contracts.get(contract.id)\n if (previous && canonical(previous) !== canonical(contract)) throw new Error(`Conflicting data contract definitions: ${contract.id}`)\n contracts.set(contract.id, JSON.parse(canonical(contract)))\n }\n this.contracts = [...contracts.values()]\n resolveDataContracts(this.contracts, Object.fromEntries(this.contracts.map(c => [c.id, c.version])))\n for (const p of plugins) this.catalog([p])\n for (const [bundleId, pluginIds] of Object.entries(project.bundles ?? {})) {\n id(bundleId)\n if (!Array.isArray(pluginIds) || !pluginIds.length || new Set(pluginIds).size !== pluginIds.length || pluginIds.some(pluginId => !this.plugins.has(pluginId))) throw new Error(`Invalid plugin bundle: ${bundleId}`)\n }\n for (const b of backends) {\n id(b.id); id(b.databaseId)\n if (this.backends.has(b.id) || !['sqlite', 'oracle', 'postgres'].includes(b.dialect) || !['shared', 'dedicated'].includes(b.mode)) throw new Error('Invalid backend target')\n if (b.mode === 'dedicated') { if (!b.tenantId) throw new Error('Dedicated backend requires tenant'); id(b.tenantId) }\n else if (b.tenantId !== undefined) throw new Error('Shared backend cannot bind a tenant')\n for (const other of backends) if (other.databaseId === b.databaseId && other.dialect !== b.dialect) throw new Error('Database dialect conflict')\n this.backends.set(b.id, b)\n }\n }\n private bundle(bundleId: string): readonly string[] {\n id(bundleId)\n const pluginIds = this.project.bundles?.[bundleId]\n if (!pluginIds) throw new Error(`Plugin bundle not registered: ${bundleId}`)\n return pluginIds\n }\n /**\n * Plans registered bundle members sequentially against a projected ledger state.\n * @param request - Lifecycle request whose pluginId names a registered bundle.\n * @returns A checksum-bound ordered bundle plan with each member's projected revision.\n * @throws Rejects unknown bundle, invalid member request/state or propagated store failures.\n * \n * @remarks\n * Disable/uninstall reverse bundle order. Planning executes no migrations or writes; projected revisions mirror member apply ordering.\n * \n * @example\n * ```typescript\n * import { PluginLifecycle, type LifecycleRequest } from '@alneas/eaos-server/lifecycle-engine';\n * export function reviewBundle(lifecycle: PluginLifecycle, request: LifecycleRequest) { return lifecycle.planBundle(request); }\n * ```\n */\n async planBundle(request: LifecycleRequest): Promise<LifecycleBundlePlan> {\n const pluginIds = [...this.bundle(request.pluginId)]\n if (request.operation === 'disable' || request.operation === 'uninstall') pluginIds.reverse()\n let projected = await this.project.store.read()\n const plans: LifecyclePlan[] = []\n for (const pluginId of pluginIds) {\n const plan = this.makePlan({ ...request, pluginId }, projected)\n plans.push(plan)\n projected = this.projectBundleState(projected, plan)\n }\n const body = { format: 1 as const, bundleId: request.pluginId, operation: request.operation, plans }\n return JSON.parse(canonical({ ...body, id: lifecycleDigest(body) }))\n }\n\n /**\n * Advance the read-only state used while constructing sequential bundle plans.\n * apply() performs these writes in the same order; mirroring them here keeps\n * each plan's revision and dependency closure valid when applyBundle() runs.\n */\n private projectBundleState(source: LifecycleState, plan: LifecyclePlan): LifecycleState {\n const state = structuredClone(source)\n state.backends[plan.backend.id] = plan.backend\n for (const k of plan.deactivate) if (state.activations[k]) state.activations[k].enabled = false\n\n if (plan.request.operation === 'install' || plan.request.operation === 'update') {\n for (const plugin of plan.plugins) state.installations[key(plan.backend.id, plugin.id)] = { release: plugin, digest: lifecycleDigest(plugin), status: 'installed' }\n if (plan.dataCatalog) {\n state.dataContracts ??= {}\n for (const contract of plan.dataCatalog.contracts) state.dataContracts[key(plan.backend.databaseId, contract.id)] = { contract, digest: lifecycleDigest(contract), status: 'installed' }\n }\n for (const step of plan.migrations) state.migrations[step.key] = { ...step.record, status: 'applied' }\n for (const step of plan.infrastructure) state.infrastructure[step.key] = { digest: step.digest, status: 'applied' }\n state.revision += 2 + (plan.migrations.length * 2) + (plan.infrastructure.length * 2)\n } else if (plan.request.operation === 'enable') {\n for (const plugin of plan.plugins) state.activations[key(plan.backend.id, plan.request.tenantId, plugin.id)] = { backendId: plan.backend.id, tenantId: plan.request.tenantId, pluginId: plugin.id, digest: lifecycleDigest(plugin), enabled: true }\n state.revision += 1\n } else if (plan.request.operation === 'uninstall') {\n delete state.installations[key(plan.backend.id, plan.request.pluginId)]\n state.revision += 1\n } else {\n state.revision += 1\n }\n return state\n }\n /**\n * Validates a reviewed bundle plan and applies its member plans in sequence.\n * @param bundlePlan - Unmodified checksum-bound bundle plan from planBundle.\n * @returns Resolves without a value after every member apply completes.\n * @throws Rejects modified/stale/misordered bundle plans, member apply failures and propagated host errors.\n * \n * @remarks\n * Members acquire their own ledger locks. There is no all-or-nothing bundle transaction; earlier members remain applied if a later member fails. Replan/reconcile before retrying uncertain outcomes.\n * \n * @example\n * ```typescript\n * import { PluginLifecycle, type LifecycleBundlePlan } from '@alneas/eaos-server/lifecycle-engine';\n * export function applyReviewedBundle(lifecycle: PluginLifecycle, plan: LifecycleBundlePlan) { return lifecycle.applyBundle(plan); }\n * ```\n */\n async applyBundle(bundlePlan: LifecycleBundlePlan): Promise<void> {\n const normalized = JSON.parse(canonical(bundlePlan)) as LifecycleBundlePlan\n const pluginIds = this.bundle(normalized.bundleId)\n const expectedIds = normalized.operation === 'disable' || normalized.operation === 'uninstall' ? [...pluginIds].reverse() : [...pluginIds]\n if (normalized.format !== 1 || !['install', 'update', 'enable', 'disable', 'uninstall'].includes(normalized.operation) || normalized.plans.length !== expectedIds.length || normalized.plans.some((plan, index) => plan.request.pluginId !== expectedIds[index] || plan.request.operation !== normalized.operation)) throw new Error('Invalid plugin bundle plan')\n const body = { format: 1 as const, bundleId: normalized.bundleId, operation: normalized.operation, plans: normalized.plans }\n if (lifecycleDigest(body) !== normalized.id) throw new Error('Stale or modified plugin bundle plan')\n for (const plan of normalized.plans) await this.apply(plan)\n }\n private release(id: string): LifecyclePlugin {\n const p = this.plugins.get(id)\n if (!p) throw new Error(`Plugin code not registered: ${id}`)\n if (!satisfies(this.frameworkVersion, p.framework, { includePrerelease: true })) throw new Error(`Incompatible framework for ${id}`)\n return p\n }\n private order(pluginId: string): LifecyclePlugin[] {\n const ordered: LifecyclePlugin[] = [], visited = new Set<string>(), visiting = new Set<string>()\n const visit = (id: string) => {\n if (visiting.has(id)) throw new Error('Plugin dependency cycle')\n if (visited.has(id)) return\n visiting.add(id)\n const p = this.release(id)\n for (const [dependency, range] of Object.entries(p.dependencies ?? {})) {\n if (!validRange(range) || !satisfies(this.release(dependency).version, range, { includePrerelease: true })) throw new Error(`Unsatisfied dependency: ${dependency}`)\n visit(dependency)\n }\n visiting.delete(id); visited.add(id); ordered.push(p)\n }\n visit(pluginId); return ordered\n }\n /**\n * Resolves the canonical schema dependency catalog for registered feature plugins.\n * \n * Read-only complete schema inventory for the selected trusted feature catalog.\n * @param pluginIds - Optional feature IDs; omitted includes all registered plugins, while an empty array selects none.\n * @returns A JSON-cloned dependency-resolved DataContractCatalog.\n * @throws Error for unknown/incompatible feature dependencies or invalid/conflicting contract requirements.\n * \n * @remarks\n * Read-only; schema dependencies never install or enable feature plugins.\n * \n * @example\n * ```typescript\n * import { PluginLifecycle } from '@alneas/eaos-server/lifecycle-engine';\n * export function schemas(lifecycle: PluginLifecycle) { return lifecycle.schemaCatalog(); }\n * ```\n */\n schemaCatalog(pluginIds?: readonly string[]): DataContractCatalog {\n const plugins = pluginIds ? pluginIds.flatMap(id => this.order(id)) : [...this.plugins.values()]\n return JSON.parse(canonical(this.catalog(plugins)))\n }\n private catalog(plugins: LifecyclePlugin[]): DataContractCatalog {\n const requirements: Record<string, string> = {}\n // Check each range independently; combining plugins must never discard a constraint.\n for (const plugin of plugins) {\n resolveDataContracts(this.contracts, plugin.schemaDependencies ?? {})\n Object.assign(requirements, plugin.schemaDependencies ?? {})\n }\n return resolveDataContracts(this.contracts, requirements)\n }\n private contractReady(state: LifecycleState, backend: BackendTarget, tenantId: string, contract: DataContract): boolean {\n const installed = state.dataContracts?.[key(backend.databaseId, contract.id)]\n if (installed?.status !== 'installed' || installed.digest !== lifecycleDigest(contract)) return false\n const identity = contract.migrationIdentity ?? `data-${contract.id}`\n return contract.migrations.every(m => {\n const record = state.migrations[key(backend.databaseId, identity, m.id, m.scope === 'tenant' ? tenantId : '*')]\n return record?.status === 'applied' && record.checksum === lifecycleDigest(m)\n })\n }\n /** Contract ledger identities may retain a feature's historical name even\n * when that feature no longer consumes the contract. Match the actual\n * immutable migration, rather than only the current feature's catalog. */\n private isContractMigration(record: MigrationRecord): boolean {\n return this.contracts.some(contract => {\n if ((contract.migrationIdentity ?? `data-${contract.id}`) !== record.pluginId) return false\n const migration = contract.migrations[record.position]\n return !!migration && migration.id === record.migrationId && lifecycleDigest(migration) === record.checksum && record.status === 'applied'\n })\n }\n private target(request: LifecycleRequest): BackendTarget {\n id(request.pluginId); id(request.backendId); id(request.tenantId)\n if (!['install', 'update', 'enable', 'disable', 'uninstall'].includes(request.operation)) throw new Error('Invalid lifecycle operation')\n const b = this.backends.get(request.backendId)\n if (!b || (b.mode === 'dedicated' && b.tenantId !== request.tenantId)) throw new Error('Backend tenant mismatch or unknown backend')\n return b\n }\n /**\n * Creates a reviewable lifecycle plan from one current ledger snapshot without executing side effects.\n * @param request - Concrete operation, registered plugin/backend and verified tenant; see LifecycleRequest.\n * @returns A deterministic checksum-bound plan carrying the snapshot revision, dependency closure, migrations and retained-data policy.\n * @throws Rejects invalid request/state, incompatible or missing dependencies, changed applied migrations, dirty ledger, unsupported dialect, tenant mismatch or propagated store failures.\n * \n * @remarks\n * Planning is read-only but may become stale immediately. Backend physical identity is immutable. Updates require appended immutable migrations and compatible schema versions; installation and enablement are separate operations.\n * \n * @example\n * ```typescript\n * import { PluginLifecycle, type LifecycleRequest } from '@alneas/eaos-server/lifecycle-engine';\n * export function review(lifecycle: PluginLifecycle, request: LifecycleRequest) { return lifecycle.plan(request); }\n * ```\n */\n async plan(request: LifecycleRequest): Promise<LifecyclePlan> { return this.makePlan(request, await this.project.store.read()) }\n private makePlan(request: LifecycleRequest, state: LifecycleState): LifecyclePlan {\n assertState(state)\n const backend = this.target(request), operation = request.operation\n if (state.backends[backend.id] && canonical(state.backends[backend.id]) !== canonical(backend)) throw new Error('Backend placement is immutable; use a new backend ID and migrate data explicitly')\n for (const b of Object.values(state.backends)) if (b.databaseId === backend.databaseId && b.dialect !== backend.dialect) throw new Error('Database dialect conflict')\n const changing = operation === 'install' || operation === 'update'\n // Disable/uninstall remain available when the new core cannot load an old plugin release.\n const installed = state.installations[key(backend.id, request.pluginId)]\n const plugins = changing || operation === 'enable' ? this.order(request.pluginId) : [installed?.release ?? this.plugins.get(request.pluginId)].filter(Boolean) as LifecyclePlugin[]\n if (!plugins.length) throw new Error('Plugin is not installed')\n if (operation === 'update' && !installed) throw new Error('Install plugin before updating')\n const dataCatalog = this.catalog(plugins)\n for (const table of dataCatalog.tables) {\n for (const [contractKey, installation] of Object.entries(state.dataContracts ?? {})) {\n if (JSON.parse(contractKey)[0] !== backend.databaseId) continue\n if (installation.contract.id !== table.contractId && dataContractTables(installation.contract.schema).has(table.name)) throw new Error(`Installed data contract already owns table: ${table.name}`)\n }\n }\n const migrations: MigrationStep[] = [], infrastructure: InfrastructureStep[] = [], deactivate = new Set<string>()\n const markDependents = (backendId: string, pluginId: string) => {\n const affected = new Set([pluginId]); let changed = true\n while (changed) {\n changed = false\n for (const [k, entry] of Object.entries(state.installations)) {\n if (JSON.parse(k)[0] !== backendId || affected.has(entry.release.id)) continue\n if (Object.keys(entry.release.dependencies ?? {}).some(d => affected.has(d))) { affected.add(entry.release.id); changed = true }\n }\n }\n for (const [k, a] of Object.entries(state.activations)) if (a.backendId === backendId && affected.has(a.pluginId)) deactivate.add(k)\n }\n if (changing) for (const contract of dataCatalog.contracts) {\n const identity = contract.migrationIdentity ?? `data-${contract.id}`\n const old = state.dataContracts?.[key(backend.databaseId, contract.id)]\n if (old && old.status !== 'installed') throw new Error(`Data contract requires reconciliation: ${contract.id}`)\n if (old && old.digest !== lifecycleDigest(contract)) {\n if (old.contract.version === contract.version) throw new Error(`Data contract changed without version bump: ${contract.id}`)\n if (lt(contract.version, old.contract.version)) throw new Error('Data contract downgrade requires explicit migration')\n if (canonical(contract.schema) !== canonical(old.contract.schema) && contract.migrations.length <= old.contract.migrations.length) throw new Error(`Schema changed without an appended migration: ${contract.id}`)\n }\n for (const [installationKey, installation] of Object.entries(state.installations)) {\n if (state.backends[JSON.parse(installationKey)[0]]?.databaseId !== backend.databaseId) continue\n const range = installation.release.schemaDependencies?.[contract.id]\n if (range && !satisfies(contract.version, range)) throw new Error(`Installed plugin requires incompatible data contract: ${installation.release.id}`)\n }\n for (const record of Object.values(state.migrations).filter(m => m.databaseId === backend.databaseId && m.pluginId === identity)) {\n const m = contract.migrations[record.position]\n if (!m || m.id !== record.migrationId || lifecycleDigest(m) !== record.checksum) throw new Error(`Applied contract migration changed or removed: ${record.migrationId}`)\n if (record.status !== 'applied') throw new Error(`Data contract migration requires reconciliation: ${record.migrationId}`)\n }\n for (const [position, m] of contract.migrations.entries()) {\n const statements = m.sql[backend.dialect]\n if (!statements?.length) throw new Error(`Data contract migration ${m.id} does not support ${backend.dialect}`)\n const tenantId = m.scope === 'tenant' ? request.tenantId : null\n const k = key(backend.databaseId, identity, m.id, tenantId ?? '*')\n if (!state.migrations[k]) migrations.push({ key: k, record: { databaseId: backend.databaseId, pluginId: identity, migrationId: m.id, position, tenantId, checksum: lifecycleDigest(m), status: 'running' }, statements })\n }\n if (!old || old.digest !== lifecycleDigest(contract) || contract.migrations.some(m => !state.migrations[key(backend.databaseId, identity, m.id, m.scope === 'tenant' ? request.tenantId : '*')])) {\n for (const activation of Object.values(state.activations)) {\n if (state.backends[activation.backendId]?.databaseId !== backend.databaseId) continue\n const release = state.installations[key(activation.backendId, activation.pluginId)]?.release\n if (release && this.catalog([release]).contracts.some(c => c.id === contract.id)) markDependents(activation.backendId, activation.pluginId)\n }\n }\n }\n if (changing) for (const p of plugins) {\n const digest = lifecycleDigest(p), old = state.installations[key(backend.id, p.id)]\n if (old && old.status !== 'installed') throw new Error(`Installation requires reconciliation: ${p.id}`)\n if (old && old.digest !== digest) {\n if (old.release.version === p.version) throw new Error(`Release changed without version bump: ${p.id}`)\n if (lt(p.version, old.release.version)) throw new Error('Plugin downgrade requires an explicit data migration')\n if (operation === 'install') throw new Error('Use update for an existing release')\n markDependents(backend.id, p.id)\n }\n for (const record of Object.values(state.migrations).filter(m => m.databaseId === backend.databaseId && m.pluginId === p.id && !this.isContractMigration(m))) {\n const m = p.migrations.find(m => m.id === record.migrationId)\n if (!m || p.migrations.indexOf(m) !== record.position || lifecycleDigest(m) !== record.checksum) throw new Error(`Applied migration changed or removed: ${record.migrationId}`)\n if (record.status !== 'applied') throw new Error(`Migration requires reconciliation: ${record.migrationId}`)\n }\n for (const m of p.migrations) {\n const statements = m.sql[backend.dialect]\n if (!statements?.length) throw new Error(`Migration ${m.id} does not support ${backend.dialect}`)\n const tenantId = m.scope === 'tenant' ? request.tenantId : null\n const k = key(backend.databaseId, p.id, m.id, tenantId ?? '*')\n if (!state.migrations[k]) {\n migrations.push({ key: k, record: { databaseId: backend.databaseId, pluginId: p.id, migrationId: m.id, position: p.migrations.indexOf(m), tenantId, checksum: lifecycleDigest(m), status: 'running' }, statements })\n // DDL can affect every running backend sharing this physical DB.\n if (m.scope === 'database') for (const b of Object.values(state.backends)) if (b.databaseId === backend.databaseId) markDependents(b.id, p.id)\n }\n }\n if (p.infrastructure) {\n const k = key(backend.id, p.id), digest = lifecycleDigest({ backend, plugin: p })\n if (state.infrastructure[k] && state.infrastructure[k].status !== 'applied') throw new Error('Infrastructure requires reconciliation')\n if (state.infrastructure[k]?.digest !== digest) infrastructure.push({ key: k, digest, plugin: p, backend })\n }\n }\n if (operation === 'disable' || operation === 'uninstall') {\n const dependents = Object.values(state.activations).filter(a => a.backendId === backend.id && a.tenantId === request.tenantId && a.enabled && a.pluginId !== request.pluginId && this.dependsOn(state, backend.id, a.pluginId, request.pluginId))\n if (dependents.length) throw new Error('Disable dependent plugins first')\n const activation = key(backend.id, request.tenantId, request.pluginId)\n if (operation === 'disable') deactivate.add(activation)\n else {\n if (Object.values(state.activations).some(a => a.backendId === backend.id && a.pluginId === request.pluginId && a.enabled)) throw new Error('Disable plugin for every tenant on this backend before uninstalling')\n if (Object.entries(state.installations).some(([k, i]) => JSON.parse(k)[0] === backend.id && i.release.id !== request.pluginId && this.dependsOn(state, backend.id, i.release.id, request.pluginId))) throw new Error('Uninstall dependent plugins first')\n }\n }\n if (operation === 'enable') for (const p of plugins) if (!this.ready(state, backend, request.tenantId, p)) throw new Error(`Install/migrate compatible release before enabling: ${p.id}`)\n const body = { format: 1 as const, revision: state.revision, frameworkVersion: this.frameworkVersion, request: { ...request }, backend, ...(dataCatalog.contracts.length ? { dataCatalog } : {}), plugins, migrations, infrastructure, deactivate: [...deactivate].sort(), infrastructureProvider: this.project.infrastructure?.identity ?? null, retainData: true as const }\n return JSON.parse(canonical({ ...body, id: lifecycleDigest(body) }))\n }\n private dependsOn(state: LifecycleState, backendId: string, pluginId: string, target: string, seen = new Set<string>()): boolean {\n if (seen.has(pluginId)) return false\n seen.add(pluginId)\n return Object.keys(state.installations[key(backendId, pluginId)]?.release.dependencies ?? {}).some(d => d === target || this.dependsOn(state, backendId, d, target, seen))\n }\n private ready(state: LifecycleState, backend: BackendTarget, tenantId: string, p: LifecyclePlugin): boolean {\n const installed = state.installations[key(backend.id, p.id)]\n if (installed?.status !== 'installed' || installed.digest !== lifecycleDigest(p)) return false\n if (Object.values(state.migrations).some(m => m.databaseId === backend.databaseId && m.pluginId === p.id && !this.isContractMigration(m) && (m.status !== 'applied' || !p.migrations.some(definition => definition.id === m.migrationId && p.migrations.indexOf(definition) === m.position && lifecycleDigest(definition) === m.checksum)))) return false\n return this.catalog([p]).contracts.every(c => this.contractReady(state, backend, tenantId, c)) && p.migrations.every(m => {\n const record = state.migrations[key(backend.databaseId, p.id, m.id, m.scope === 'tenant' ? tenantId : '*')]\n return record?.status === 'applied' && record.checksum === lifecycleDigest(m)\n }) && (!p.infrastructure || state.infrastructure[key(backend.id, p.id)]?.digest === lifecycleDigest({ backend, plugin: p }) && state.infrastructure[key(backend.id, p.id)]?.status === 'applied')\n }\n /**\n * Checks that a tenant activation and its entire registered dependency closure match ready ledger releases.\n * @param backendId - Registered execution backend ID.\n * @param tenantId - Verified concrete tenant ID.\n * @param pluginId - Registered feature ID to check.\n * @returns True only when matching installation, migrations, infrastructure and activation digests are all ready; false for missing/incompatible readiness.\n * @throws Rejects malformed IDs/state, unknown or mismatched backend/tenant and store failures.\n * \n * @remarks\n * Read-only admission check; a later state change can revoke access. Host must still enforce current tenant/resource authorization.\n * \n * @example\n * ```typescript\n * import { PluginLifecycle } from '@alneas/eaos-server/lifecycle-engine';\n * export function admitted(lifecycle: PluginLifecycle, backendId: string, tenantId: string, pluginId: string) { return lifecycle.isEnabled(backendId, tenantId, pluginId); }\n * ```\n */\n async isEnabled(backendId: string, tenantId: string, pluginId: string): Promise<boolean> {\n const state = await this.project.store.read(); assertState(state)\n return this.enabledInState(state, backendId, tenantId, pluginId)\n }\n private enabledInState(state: LifecycleState, backendId: string, tenantId: string, pluginId: string): boolean {\n const backend = this.target({ operation: 'enable', backendId, tenantId, pluginId })\n if (!state.backends[backend.id] || canonical(state.backends[backend.id]) !== canonical(backend)) return false\n let plugins: LifecyclePlugin[]\n try { plugins = this.order(pluginId) } catch { return false }\n return plugins.every(p => this.ready(state, backend, tenantId, p) && state.activations[key(backendId, tenantId, p.id)]?.enabled === true && state.activations[key(backendId, tenantId, p.id)]?.digest === lifecycleDigest(p))\n }\n /**\n * Reads inventory including registered uninstalled code and orphaned historical installations.\n * \n * One read-only control-state snapshot; includes orphaned installation records and registered, uninstalled code.\n * @param options - Optional backendId and tenantId filters; omitted returns all known inventory.\n * @returns A revision-bound inventory with effective enabled state distinct from requested activation.\n * @throws Rejects invalid filter IDs, unknown backend, corrupt installation/activation records, dedicated tenant mismatch or store failure.\n * \n * @remarks\n * Performs one ledger read without writes. Dedicated backends for another tenant are omitted unless explicitly requested, in which case the request rejects.\n * \n * @example\n * ```typescript\n * import { PluginLifecycle } from '@alneas/eaos-server/lifecycle-engine';\n * export function inventory(lifecycle: PluginLifecycle) { return lifecycle.list(); }\n * ```\n */\n async list(options: { \n /**\n * Optional exact backend filter; unknown backends reject.\n */\n backendId?: string; \n /**\n * Optional concrete tenant filter; dedicated backend scope must match.\n */\n tenantId?: string } = {}): Promise<LifecycleInventory> {\n if (options.backendId !== undefined) id(options.backendId)\n if (options.tenantId !== undefined) id(options.tenantId)\n const state = await this.project.store.read(); assertState(state)\n const installations = Object.entries(state.installations).map(([entryKey, installation]) => {\n const parts = JSON.parse(entryKey)\n if (!Array.isArray(parts) || parts.length !== 2 || parts.some(p => typeof p !== 'string')) throw new Error('Invalid installation key')\n const [backendId, pluginId] = parts as [string, string]\n id(backendId); id(pluginId)\n if (installation.release?.id !== pluginId || !valid(installation.release.version) || !['installing', 'installed', 'failed'].includes(installation.status)) throw new Error('Invalid installation record')\n return { backendId, pluginId }\n })\n const activations = Object.values(state.activations)\n const backendIds = new Set([...this.backends.keys(), ...Object.keys(state.backends), ...installations.map(p => p.backendId), ...activations.map(p => p.backendId)])\n for (const backendId of backendIds) id(backendId)\n for (const activation of activations) {\n id(activation.tenantId); id(activation.pluginId)\n if (typeof activation.enabled !== 'boolean') throw new Error('Invalid activation record')\n }\n if (options.backendId && !backendIds.has(options.backendId)) throw new Error(`Unknown backend: ${options.backendId}`)\n const targets: (string | null)[] = options.backendId ? [options.backendId] : backendIds.size ? [...backendIds].sort() : [null]\n const plugins: LifecycleInventoryEntry[] = []\n for (const backendId of targets) {\n const backend = backendId ? this.backends.get(backendId) : undefined\n if (options.tenantId && backend?.mode === 'dedicated' && backend.tenantId !== options.tenantId) {\n if (options.backendId) throw new Error('Tenant does not belong to dedicated backend')\n continue\n }\n const pluginIds = new Set([...this.plugins.keys(), ...installations.filter(p => p.backendId === backendId).map(p => p.pluginId), ...activations.filter(p => p.backendId === backendId).map(p => p.pluginId)])\n for (const pluginId of [...pluginIds].sort()) {\n const registered = this.plugins.get(pluginId)\n const installed = backendId ? state.installations[key(backendId, pluginId)] : undefined\n const tenantIds = options.tenantId ? [options.tenantId] : [...new Set(activations.filter(p => p.backendId === backendId && p.pluginId === pluginId).map(p => p.tenantId))].sort()\n plugins.push({\n pluginId, backendId, backendConfigured: !!backend,\n registeredVersion: registered?.version ?? null, installedVersion: installed?.release.version ?? null,\n installationStatus: installed?.status ?? 'not-installed',\n releaseMatches: installed ? !!registered && installed.digest === lifecycleDigest(registered) : null,\n tenants: tenantIds.map(tenantId => ({\n tenantId, requestedEnabled: backendId ? state.activations[key(backendId, tenantId, pluginId)]?.enabled === true : false,\n enabled: !!backend && !!backendId && (backend.mode !== 'dedicated' || backend.tenantId === tenantId) && this.enabledInState(state, backendId, tenantId, pluginId),\n })),\n })\n }\n }\n return { format: 1, revision: state.revision, frameworkVersion: this.frameworkVersion, plugins }\n }\n /**\n * Runs a host callback only after the current plugin dependency closure passes lifecycle admission.\n * @typeParam T - Value resolved by the admitted callback.\n * @param backendId - Registered backend ID.\n * @param tenantId - Verified concrete tenant ID.\n * @param pluginId - Feature plugin ID.\n * @param callback - Async work invoked once after admission; must enforce tenant/resource authorization itself.\n * @returns The callback result without cloning.\n * @throws Rejects inactive plugin, lifecycle/store validation failure or callback rejection.\n * \n * @remarks\n * The admission check does not hold a lock or pin activation throughout callback execution. Host quiesce/drain and live authorization remain required.\n * \n * @example\n * ```typescript\n * import { PluginLifecycle } from '@alneas/eaos-server/lifecycle-engine';\n * export function runAdmitted<T>(lifecycle: PluginLifecycle, backendId: string, tenantId: string, pluginId: string, work: () => Promise<T>) { return lifecycle.run(backendId, tenantId, pluginId, work); }\n * ```\n */\n async run<T>(backendId: string, tenantId: string, pluginId: string, callback: () => Promise<T>): Promise<T> {\n if (!await this.isEnabled(backendId, tenantId, pluginId)) throw new Error('Plugin is inactive')\n return callback()\n }\n /**\n * Checks plan freshness and invokes host infrastructure previews without applying ledger changes.\n * @param plan - Unmodified lifecycle plan to preview.\n * @returns Preview results in infrastructure-step order, or an empty array when no infrastructure is needed.\n * @throws Rejects stale/modified plan, missing infrastructure adapter or propagated plan/preview errors.\n * \n * @remarks\n * Infrastructure previews run concurrently through Promise.all. Host preview adapters own any external read/preview effects; this method executes no migrations.\n * \n * @example\n * ```typescript\n * import { PluginLifecycle, type LifecyclePlan } from '@alneas/eaos-server/lifecycle-engine';\n * export function preview(lifecycle: PluginLifecycle, plan: LifecyclePlan) { return lifecycle.preview(plan); }\n * ```\n */\n async preview(plan: LifecyclePlan): Promise<unknown[]> {\n const fresh = await this.plan(plan.request)\n if (canonical(fresh) !== canonical(plan)) throw new Error('Stale or modified lifecycle plan')\n if (plan.infrastructure.length && !this.project.infrastructure) throw new Error('Infrastructure executor is required')\n return Promise.all(plan.infrastructure.map(s => this.project.infrastructure!.preview(s)))\n }\n /**\n * Revalidates and executes a reviewed lifecycle plan while holding the host's exclusive ledger lock.\n * @param plan - Unmodified plan bound to the current ledger revision and registered configuration.\n * @returns Resolves without a value after ledger updates and requested side effects complete.\n * @throws Rejects stale/modified plan, missing executors/quiesce, reconciliation conflicts or host store, migration, infrastructure or drain failures.\n * \n * @remarks\n * Before upgrade side effects, affected activations are disabled durably and all-instance quiesce is required. Infrastructure/migration running/applied/failed receipts are persisted separately. Errors can follow partial external success; no automatic rollback/retry occurs. Uninstall retains business data and migration history.\n * \n * @example\n * ```typescript\n * import { PluginLifecycle, type LifecyclePlan } from '@alneas/eaos-server/lifecycle-engine';\n * export function applyReviewed(lifecycle: PluginLifecycle, plan: LifecyclePlan) { return lifecycle.apply(plan); }\n * ```\n */\n async apply(plan: LifecyclePlan): Promise<void> {\n plan = JSON.parse(canonical(plan))\n await this.project.store.withLock(async writer => {\n const state = await writer.read(), fresh = this.makePlan(plan.request, state)\n if (canonical(fresh) !== canonical(plan)) throw new Error('Stale or modified lifecycle plan')\n if (plan.infrastructure.length && !this.project.infrastructure) throw new Error('Infrastructure executor is required')\n if (['install', 'update'].includes(plan.request.operation) && plan.deactivate.length && !this.project.quiesce) throw new Error('A quiesce executor is required for active deployments')\n const save = async () => { state.revision++; await writer.write(state) }\n const { request, backend } = plan\n state.backends[backend.id] = backend\n for (const k of plan.deactivate) if (state.activations[k]) state.activations[k].enabled = false\n if (request.operation === 'install' || request.operation === 'update') {\n for (const p of plan.plugins) state.installations[key(backend.id, p.id)] = { release: p, digest: lifecycleDigest(p), status: 'installing' }\n state.dataContracts ??= {}\n for (const contract of plan.dataCatalog?.contracts ?? []) state.dataContracts[key(backend.databaseId, contract.id)] = { contract, digest: lifecycleDigest(contract), status: 'installing' }\n // Persist inactive status BEFORE any DB or infrastructure effects.\n await save()\n try {\n if (plan.deactivate.length) await this.project.quiesce!(plan.deactivate.map(k => state.activations[k]))\n for (const step of plan.infrastructure) {\n state.infrastructure[step.key] = { digest: step.digest, status: 'running' }; await save()\n try { await this.project.infrastructure!.apply(step) }\n catch (error) { state.infrastructure[step.key].status = 'failed'; await save(); throw error }\n state.infrastructure[step.key].status = 'applied'; await save()\n }\n for (const step of plan.migrations) {\n state.migrations[step.key] = { ...step.record }; await save()\n try { await this.project.migrate(step, backend) }\n catch (error) { state.migrations[step.key].status = 'failed'; await save(); throw error }\n state.migrations[step.key].status = 'applied'; await save()\n }\n for (const contract of plan.dataCatalog?.contracts ?? []) state.dataContracts![key(backend.databaseId, contract.id)].status = 'installed'\n for (const p of plan.plugins) state.installations[key(backend.id, p.id)].status = 'installed'\n } catch (error) {\n for (const contract of plan.dataCatalog?.contracts ?? []) state.dataContracts![key(backend.databaseId, contract.id)].status = 'failed'\n for (const p of plan.plugins) state.installations[key(backend.id, p.id)].status = 'failed'\n await save(); throw error\n }\n } else if (request.operation === 'enable') {\n for (const p of plan.plugins) state.activations[key(backend.id, request.tenantId, p.id)] = { backendId: backend.id, tenantId: request.tenantId, pluginId: p.id, digest: lifecycleDigest(p), enabled: true }\n } else if (request.operation === 'uninstall') delete state.installations[key(backend.id, request.pluginId)]\n await save()\n })\n }\n}\n","{\n \"name\": \"@alneas/eaos-server\",\n \"version\": \"0.2.0\",\n \"type\": \"module\",\n \"license\": \"MIT\",\n \"description\": \"EAOS server public package\",\n \"exports\": {\n \"./db/local-first-sqlite-adapter\": {\n \"types\": \"./dist/db-package/db/local-first-sqlite-adapter.d.ts\",\n \"import\": \"./dist/db-package/db/local-first-sqlite-adapter.js\"\n },\n \"./db\": {\n \"types\": \"./dist/db-package/index.d.ts\",\n \"import\": \"./dist/db-package/index.js\"\n },\n \"./db/migration/aggregator\": {\n \"types\": \"./dist/db-package/migration/aggregator.d.ts\",\n \"import\": \"./dist/db-package/migration/aggregator.js\"\n },\n \"./db/migration\": {\n \"types\": \"./dist/db-package/migration/index.d.ts\",\n \"import\": \"./dist/db-package/migration/index.js\"\n },\n \"./lifecycle-engine/backend-migration\": {\n \"types\": \"./dist/lifecycle-engine/backend-migration.d.ts\",\n \"import\": \"./dist/lifecycle-engine/backend-migration.js\"\n },\n \"./lifecycle-engine\": {\n \"types\": \"./dist/lifecycle-engine/index.d.ts\",\n \"import\": \"./dist/lifecycle-engine/index.js\"\n },\n \"./platform/artifacts\": {\n \"types\": \"./dist/lifecycle-engine/platform/artifacts.d.ts\",\n \"import\": \"./dist/lifecycle-engine/platform/artifacts.js\"\n },\n \"./platform/control-plane\": {\n \"types\": \"./dist/lifecycle-engine/platform/control-plane.d.ts\",\n \"import\": \"./dist/lifecycle-engine/platform/control-plane.js\"\n },\n \"./platform/database-router\": {\n \"types\": \"./dist/lifecycle-engine/platform/database-router.d.ts\",\n \"import\": \"./dist/lifecycle-engine/platform/database-router.js\"\n },\n \"./platform/deployment-placements\": {\n \"types\": \"./dist/lifecycle-engine/platform/deployment-placements.d.ts\",\n \"import\": \"./dist/lifecycle-engine/platform/deployment-placements.js\"\n },\n \"./platform/deployment\": {\n \"types\": \"./dist/lifecycle-engine/platform/deployment.d.ts\",\n \"import\": \"./dist/lifecycle-engine/platform/deployment.js\"\n },\n \"./platform\": {\n \"types\": \"./dist/lifecycle-engine/platform/index.d.ts\",\n \"import\": \"./dist/lifecycle-engine/platform/index.js\"\n },\n \"./platform/runtime\": {\n \"types\": \"./dist/lifecycle-engine/platform/runtime.d.ts\",\n \"import\": \"./dist/lifecycle-engine/platform/runtime.js\"\n },\n \"./platform/site-publication\": {\n \"types\": \"./dist/lifecycle-engine/platform/site-publication.d.ts\",\n \"import\": \"./dist/lifecycle-engine/platform/site-publication.js\"\n },\n \"./platform/user-directory\": {\n \"types\": \"./dist/lifecycle-engine/platform/user-directory.d.ts\",\n \"import\": \"./dist/lifecycle-engine/platform/user-directory.js\"\n },\n \"./lifecycle-engine/baseline\": {\n \"types\": \"./dist/lifecycle-engine/baseline.d.ts\",\n \"import\": \"./dist/lifecycle-engine/baseline.js\"\n },\n \"./storage\": {\n \"types\": \"./dist/storage/index.d.ts\",\n \"import\": \"./dist/storage/index.js\"\n },\n \"./storage/s3-compatible\": {\n \"types\": \"./dist/storage/s3-compatible.d.ts\",\n \"import\": \"./dist/storage/s3-compatible.js\"\n },\n \"./agentic/agent-jobs\": {\n \"types\": \"./dist/agentic/agent-jobs.d.ts\",\n \"import\": \"./dist/agentic/agent-jobs.js\"\n },\n \"./agentic/agent-node\": {\n \"types\": \"./dist/agentic/agent-node.d.ts\",\n \"import\": \"./dist/agentic/agent-node.js\"\n },\n \"./agentic/agent-runner\": {\n \"types\": \"./dist/agentic/agent-runner.d.ts\",\n \"import\": \"./dist/agentic/agent-runner.js\"\n },\n \"./agentic/ai-broker\": {\n \"types\": \"./dist/agentic/ai-broker.d.ts\",\n \"import\": \"./dist/agentic/ai-broker.js\"\n },\n \"./agentic/atomic-checkpointer\": {\n \"types\": \"./dist/agentic/atomic-checkpointer.d.ts\",\n \"import\": \"./dist/agentic/atomic-checkpointer.js\"\n },\n \"./agentic/autonomous-worker\": {\n \"types\": \"./dist/agentic/autonomous-worker.d.ts\",\n \"import\": \"./dist/agentic/autonomous-worker.js\"\n },\n \"./agentic/event-bridge\": {\n \"types\": \"./dist/agentic/event-bridge.d.ts\",\n \"import\": \"./dist/agentic/event-bridge.js\"\n },\n \"./agentic/executor\": {\n \"types\": \"./dist/agentic/executor.d.ts\",\n \"import\": \"./dist/agentic/executor.js\"\n },\n \"./agentic/graph-projection\": {\n \"types\": \"./dist/agentic/graph-projection.d.ts\",\n \"import\": \"./dist/agentic/graph-projection.js\"\n },\n \"./agentic/graph\": {\n \"types\": \"./dist/agentic/graph.d.ts\",\n \"import\": \"./dist/agentic/graph.js\"\n },\n \"./agentic\": {\n \"types\": \"./dist/agentic/index.d.ts\",\n \"import\": \"./dist/agentic/index.js\"\n },\n \"./agentic/local-runner\": {\n \"types\": \"./dist/agentic/local-runner.d.ts\",\n \"import\": \"./dist/agentic/local-runner.js\"\n },\n \"./agentic/remote-executor\": {\n \"types\": \"./dist/agentic/remote-executor.d.ts\",\n \"import\": \"./dist/agentic/remote-executor.js\"\n },\n \"./agentic/types\": {\n \"types\": \"./dist/agentic/types.d.ts\",\n \"import\": \"./dist/agentic/types.js\"\n },\n \"./agentic/workflow-catalog\": {\n \"types\": \"./dist/agentic/workflow-catalog.d.ts\",\n \"import\": \"./dist/agentic/workflow-catalog.js\"\n },\n \"./agentic/workflow-compiler\": {\n \"types\": \"./dist/agentic/workflow-compiler.d.ts\",\n \"import\": \"./dist/agentic/workflow-compiler.js\"\n },\n \"./agentic/workflow-coordinator\": {\n \"types\": \"./dist/agentic/workflow-coordinator.d.ts\",\n \"import\": \"./dist/agentic/workflow-coordinator.js\"\n },\n \"./agentic/workflow-manager\": {\n \"types\": \"./dist/agentic/workflow-manager.d.ts\",\n \"import\": \"./dist/agentic/workflow-manager.js\"\n },\n \"./agentic/workflow-registry\": {\n \"types\": \"./dist/agentic/workflow-registry.d.ts\",\n \"import\": \"./dist/agentic/workflow-registry.js\"\n },\n \"./auth-hooks/api-key\": {\n \"types\": \"./dist/auth-hooks/api-key.d.ts\",\n \"import\": \"./dist/auth-hooks/api-key.js\"\n },\n \"./auth-hooks\": {\n \"types\": \"./dist/auth-hooks/index.d.ts\",\n \"import\": \"./dist/auth-hooks/index.js\"\n },\n \"./browser-auth/account-memberships\": {\n \"types\": \"./dist/browser-auth/account-memberships.d.ts\",\n \"import\": \"./dist/browser-auth/account-memberships.js\"\n },\n \"./browser-auth\": {\n \"types\": \"./dist/browser-auth/index.d.ts\",\n \"import\": \"./dist/browser-auth/index.js\"\n },\n \"./browser-auth/kratos-session\": {\n \"types\": \"./dist/browser-auth/kratos-session.d.ts\",\n \"import\": \"./dist/browser-auth/kratos-session.js\"\n },\n \"./browser-auth/platform-session\": {\n \"types\": \"./dist/browser-auth/platform-session.d.ts\",\n \"import\": \"./dist/browser-auth/platform-session.js\"\n },\n \"./browser-auth/public-memberships\": {\n \"types\": \"./dist/browser-auth/public-memberships.d.ts\",\n \"import\": \"./dist/browser-auth/public-memberships.js\"\n },\n \"./cache\": {\n \"types\": \"./dist/cache/index.d.ts\",\n \"import\": \"./dist/cache/index.js\"\n },\n \"./engine\": {\n \"types\": \"./dist/engine.d.ts\",\n \"import\": \"./dist/engine.js\"\n },\n \"./execution\": {\n \"types\": \"./dist/execution/index.d.ts\",\n \"import\": \"./dist/execution/index.js\"\n },\n \"./extensions\": {\n \"types\": \"./dist/extensions/index.d.ts\",\n \"import\": \"./dist/extensions/index.js\"\n },\n \"./health\": {\n \"types\": \"./dist/health/index.d.ts\",\n \"import\": \"./dist/health/index.js\"\n },\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\"\n },\n \"./lifecycle\": {\n \"types\": \"./dist/lifecycle/index.d.ts\",\n \"import\": \"./dist/lifecycle/index.js\"\n },\n \"./mcp\": {\n \"types\": \"./dist/mcp.d.ts\",\n \"import\": \"./dist/mcp.js\"\n },\n \"./middleware/auth\": {\n \"types\": \"./dist/middleware/auth.d.ts\",\n \"import\": \"./dist/middleware/auth.js\"\n },\n \"./middleware/error-handler\": {\n \"types\": \"./dist/middleware/error-handler.d.ts\",\n \"import\": \"./dist/middleware/error-handler.js\"\n },\n \"./middleware/module-guard\": {\n \"types\": \"./dist/middleware/module-guard.d.ts\",\n \"import\": \"./dist/middleware/module-guard.js\"\n },\n \"./platform-admin\": {\n \"types\": \"./dist/platform-admin/index.d.ts\",\n \"import\": \"./dist/platform-admin/index.js\"\n },\n \"./platform-admin/store\": {\n \"types\": \"./dist/platform-admin/store.d.ts\",\n \"import\": \"./dist/platform-admin/store.js\"\n },\n \"./plugin-data/annotations\": {\n \"types\": \"./dist/plugin-data/annotations.d.ts\",\n \"import\": \"./dist/plugin-data/annotations.js\"\n },\n \"./plugin-data/atomic-context\": {\n \"types\": \"./dist/plugin-data/atomic-context.d.ts\",\n \"import\": \"./dist/plugin-data/atomic-context.js\"\n },\n \"./plugin-data/atomic\": {\n \"types\": \"./dist/plugin-data/atomic.d.ts\",\n \"import\": \"./dist/plugin-data/atomic.js\"\n },\n \"./plugin-data/audit\": {\n \"types\": \"./dist/plugin-data/audit.d.ts\",\n \"import\": \"./dist/plugin-data/audit.js\"\n },\n \"./plugin-data/commands\": {\n \"types\": \"./dist/plugin-data/commands.d.ts\",\n \"import\": \"./dist/plugin-data/commands.js\"\n },\n \"./plugin-data/composite\": {\n \"types\": \"./dist/plugin-data/composite.d.ts\",\n \"import\": \"./dist/plugin-data/composite.js\"\n },\n \"./plugin-data/delivery\": {\n \"types\": \"./dist/plugin-data/delivery.d.ts\",\n \"import\": \"./dist/plugin-data/delivery.js\"\n },\n \"./plugin-data\": {\n \"types\": \"./dist/plugin-data/index.d.ts\",\n \"import\": \"./dist/plugin-data/index.js\"\n },\n \"./plugin-data/json-documents\": {\n \"types\": \"./dist/plugin-data/json-documents.d.ts\",\n \"import\": \"./dist/plugin-data/json-documents.js\"\n },\n \"./plugin-data/outbox\": {\n \"types\": \"./dist/plugin-data/outbox.d.ts\",\n \"import\": \"./dist/plugin-data/outbox.js\"\n },\n \"./plugin-data/scoped-records\": {\n \"types\": \"./dist/plugin-data/scoped-records.d.ts\",\n \"import\": \"./dist/plugin-data/scoped-records.js\"\n },\n \"./sql-lifecycle\": {\n \"types\": \"./dist/sql-lifecycle/index.d.ts\",\n \"import\": \"./dist/sql-lifecycle/index.js\"\n },\n \"./tenant\": {\n \"types\": \"./dist/tenant.d.ts\",\n \"import\": \"./dist/tenant.js\"\n },\n \"./workspace-context\": {\n \"types\": \"./dist/workspace-context.d.ts\",\n \"import\": \"./dist/workspace-context.js\"\n },\n \"./entitlements\": {\n \"types\": \"./dist/entitlements/index.d.ts\",\n \"import\": \"./dist/entitlements/index.js\"\n },\n \"./plugin-sdk\": {\n \"types\": \"./dist/plugin-sdk.d.ts\",\n \"import\": \"./dist/plugin-sdk.js\"\n },\n \"./execution/chat\": {\n \"types\": \"./dist/execution/chat.d.ts\",\n \"import\": \"./dist/execution/chat.js\"\n },\n \"./execution/tool-agent\": {\n \"types\": \"./dist/execution/tool-agent.d.ts\",\n \"import\": \"./dist/execution/tool-agent.js\"\n }\n },\n \"files\": [\n \"dist\",\n \"docs\",\n \"README.md\",\n \"README.ja.md\",\n \"LICENSE\",\n \"CHANGELOG.md\",\n \"README.ja.md\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"test\": \"node ../../scripts/run-source-tests.mjs\"\n },\n \"publishConfig\": {\n \"registry\": \"https://registry.npmjs.org\",\n \"access\": \"public\"\n },\n \"engines\": {\n \"node\": \">=24.0.0\"\n },\n \"devDependencies\": {\n \"tsup\": \"^9.0.0\",\n \"typescript\": \"^6.0.3\",\n \"@types/node\": \"^22.20.5\",\n \"@types/semver\": \"^7.8.0\",\n \"@alneas/appkit-core\": \"0.2.0\"\n },\n \"dependencies\": {\n \"@alneas/eaos-core\": \"^0.2.0\",\n \"semver\": \"^7.8.5\",\n \"hono\": \"^4.13.13\",\n \"ajv\": \"^8.20.0\",\n \"ajv-formats\": \"^3.0.1\",\n \"@langchain/langgraph\": \"^1.5.0\"\n },\n \"peerDependencies\": {\n \"@alneas/appkit-core\": \"0.2.0\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/dataarthub/eaos.git\",\n \"directory\": \"packages/server\"\n },\n \"homepage\": \"https://tech-docs.alneas.com/eaos-workspace/\",\n \"bugs\": {\n \"url\": \"https://github.com/dataarthub/eaos/issues\"\n }\n}\n","import { lifecycleDigest, type BackendTarget } from './index'\n\n/**\n * Explicit complete fleet or nonempty concrete tenant selection for a reviewed data move.\n * \n * @see planBackendMigration for canonical integration usage.\n */\nexport type BackendMigrationScope =\n | { \n /**\n * Scope discriminator: all-tenants includes the fleet; tenants names a concrete bounded selection.\n */\n kind: 'all-tenants' }\n | { \n /**\n * Scope discriminator: all-tenants includes the fleet; tenants names a concrete bounded selection.\n */\n kind: 'tenants'; \n /**\n * Nonempty distinct concrete tenant IDs; dedicated endpoint tenants must be included.\n */\n tenantIds: readonly string[] }\n\n/**\n * Operator-reviewed source/target database move with bounded scope and reason.\n * \n * @see planBackendMigration for canonical integration usage.\n */\nexport interface BackendMigrationRequest {\n /**\n * Nonblank stable migration identity, up to 256 characters.\n */\n migrationId: string\n /**\n * Existing backend whose data remains retained.\n */\n source: BackendTarget\n /**\n * Different backend and physical database identity.\n */\n target: BackendTarget\n /**\n * All tenants or nonempty unique explicit tenant IDs; dedicated endpoints require their tenant in explicit scope.\n */\n scope: BackendMigrationScope\n /**\n * Nonempty unique registered-style feature IDs covered by the move.\n */\n pluginIds: readonly string[]\n /**\n * Parseable request timestamp.\n */\n requestedAt: string\n /**\n * Nonblank reviewed operator reason, at most 1024 characters.\n */\n reason: string\n}\n\n/**\n * Deterministic five-phase non-destructive data migration plan.\n * \n * @see planBackendMigration for canonical integration usage.\n */\nexport interface BackendMigrationPlan {\n /**\n * Plan discriminator; currently 1.\n */\n format: 1\n /**\n * Canonical digest of the normalized request and phase/safety flags.\n */\n id: string\n /**\n * Cloned request with sorted plugin and explicit tenant IDs.\n */\n request: BackendMigrationRequest\n /**\n * Ordered prepare/copy/verify/cutover/retain-source execution phases.\n */\n phases: readonly ['prepare', 'copy', 'verify', 'cutover', 'retain-source']\n /**\n * Always true; the host must drain affected execution before switching.\n */\n requiresQuiesce: true\n /**\n * Always true; source data must remain available.\n */\n retainSourceData: true\n /**\n * Always false; dropping source data is outside this plan.\n */\n destructiveOperations: false\n}\n\n/**\n * Host-reported match for one tenant/plugin copy at observed revisions.\n * \n * @see planBackendMigration for canonical integration usage.\n */\nexport interface BackendMigrationVerification {\n /**\n * Concrete verified tenant covered by the plan.\n */\n tenantId: string\n /**\n * Planned feature whose records were compared.\n */\n pluginId: string\n /**\n * Nonnegative safe revision observed at source.\n */\n sourceRevision: number\n /**\n * Nonnegative safe revision observed at target; not required to numerically equal source.\n */\n targetRevision: number\n /**\n * True only when the host comparison passed; validator does not perform the comparison.\n */\n matched: boolean\n}\n\n/**\n * Host verification evidence bound to a reviewed source/target migration.\n * \n * @see planBackendMigration for canonical integration usage.\n */\nexport interface BackendMigrationVerificationReport {\n /**\n * Plan request migration identity.\n */\n migrationId: string\n /**\n * Exact source backend identity.\n */\n sourceBackendId: string\n /**\n * Exact target backend identity.\n */\n targetBackendId: string\n /**\n * Parseable verification timestamp.\n */\n checkedAt: string\n /**\n * Nonempty matched in-scope record reports; host must establish exhaustive coverage.\n */\n records: readonly BackendMigrationVerification[]\n /**\n * Host declaration that verification passed; must be true for acceptance.\n */\n passed: boolean\n}\n\n/**\n * Host-reported routing switch retaining the original database for recovery.\n * \n * @see planBackendMigration for canonical integration usage.\n */\nexport interface BackendMigrationCutover {\n /**\n * Plan migration identity.\n */\n migrationId: string\n /**\n * Exact reviewed target backend.\n */\n targetBackendId: string\n /**\n * Nonnegative safe routing revision after cutover.\n */\n routingRevision: number\n /**\n * Parseable routing-switch timestamp.\n */\n cutoverAt: string\n /**\n * Must be true; destructive source cleanup is outside this contract.\n */\n sourceRetained: true\n}\n\n/**\n * Host-owned migration phases operating on real adapters and retained source storage.\n * \n * @see planBackendMigration for canonical integration usage.\n */\nexport interface BackendMigrationExecutor {\n /**\n * Provision/adopt the reviewed target and establish quiescence without deleting source data.\n * @param plan - Reviewed unmodified backend migration plan; host must preserve quiescence and source data.\n * @returns Resolves without a value after target preparation and required quiescence.\n * @throws Host adapter or callback failures reject the returned Promise; side effects may already be partially complete.\n \n * @example\n * ```typescript\n * import type { BackendMigrationExecutor, BackendMigrationPlan } from '@alneas/eaos-server/lifecycle-engine';\n * export async function prepareReviewed(executor: BackendMigrationExecutor, plan: BackendMigrationPlan) {\n * // The host approves exact targets and serializes migration writers.\n * await executor.prepare(plan);\n * }\n * ```\n */\n prepare(plan: BackendMigrationPlan): Promise<void>\n /**\n * Copy the scoped tenant/plugin data into the target and retain source state.\n * @param plan - Reviewed unmodified backend migration plan; host must preserve quiescence and source data.\n * @returns Resolves without a value after the scoped copy completes, with source retained.\n * @throws Host adapter or callback failures reject the returned Promise; side effects may already be partially complete.\n \n * @example\n * ```typescript\n * import type { BackendMigrationExecutor, BackendMigrationPlan } from '@alneas/eaos-server/lifecycle-engine';\n * export async function copyReviewed(executor: BackendMigrationExecutor, plan: BackendMigrationPlan) {\n * // The host approves exact targets and serializes migration writers.\n * await executor.copy(plan);\n * }\n * ```\n */\n copy(plan: BackendMigrationPlan): Promise<void>\n /**\n * Produce nonempty exhaustive host match evidence for the plan's scope.\n * @param plan - Reviewed unmodified backend migration plan; host must preserve quiescence and source data.\n * @returns The host verification report; caller must check it against the reviewed plan.\n * @throws Host adapter or callback failures reject the returned Promise; side effects may already be partially complete.\n \n * @example\n * ```typescript\n * import type { BackendMigrationExecutor, BackendMigrationPlan } from '@alneas/eaos-server/lifecycle-engine';\n * export async function verifyReviewed(executor: BackendMigrationExecutor, plan: BackendMigrationPlan) {\n * // The host approves exact targets and serializes migration writers.\n * return executor.verify(plan);\n * }\n * ```\n */\n verify(plan: BackendMigrationPlan): Promise<BackendMigrationVerificationReport>\n /**\n * Switch routing only after valid verification, retaining source and returning a cutover receipt.\n * @param plan - Reviewed unmodified backend migration plan; host must preserve quiescence and source data.\n * @param verification - Matching passed host verification report; establish complete copy coverage before cutover.\n * @returns A source-retaining routing cutover receipt after accepted verification.\n * @throws Host adapter or callback failures reject the returned Promise; side effects may already be partially complete.\n \n * @example\n * ```typescript\n * import type { BackendMigrationExecutor, BackendMigrationPlan, BackendMigrationVerificationReport } from '@alneas/eaos-server/lifecycle-engine';\n * export async function cutoverReviewed(executor: BackendMigrationExecutor, plan: BackendMigrationPlan, verification: BackendMigrationVerificationReport) {\n * // Supply current, successful evidence for this exact reviewed plan.\n * return executor.cutover(plan, verification);\n * }\n * ```\n */\n cutover(plan: BackendMigrationPlan, verification: BackendMigrationVerificationReport): Promise<BackendMigrationCutover>\n}\n\nfunction text(value: unknown, name: string, max = 256): string {\n if (typeof value !== 'string' || !value.trim() || value.length > max) throw new Error(`Invalid migration ${name}`)\n return value\n}\n\nfunction assertBackend(backend: BackendTarget, name: string): void {\n if (!backend || typeof backend !== 'object') throw new Error(`Invalid migration ${name}`)\n text(backend?.id, `${name} id`)\n text(backend?.databaseId, `${name} databaseId`)\n if (!['sqlite', 'postgres', 'oracle'].includes(backend.dialect) || !['shared', 'dedicated'].includes(backend.mode)) throw new Error(`Invalid migration ${name}`)\n if (backend.mode === 'dedicated' && !backend.tenantId) throw new Error(`Dedicated ${name} requires tenantId`)\n if (backend.mode === 'shared' && backend.tenantId !== undefined) throw new Error(`Shared ${name} cannot pin tenantId`)\n}\n\n/**\n * Creates a deterministic source-retaining migration plan without touching either database.\n * \n * Create a reviewable fleet/tenant data-migration plan without touching either backend.\n * @param request - Reviewed distinct physical source/target backends, concrete tenant scope, nonempty unique plugin IDs, timestamp and reason.\n * @returns A shallow-frozen plan with sorted cloned scopes/plugin IDs and five ordered phases.\n * @throws Error for malformed request, same source/target identity, invalid scope or dedicated-tenant mismatch.\n * \n * @remarks\n * Dedicated backend tenants must appear in explicit tenant scope. No executor, lock, provisioning, copy or cutover runs during planning; host must implement quiescence.\n * \n * @example\n * ```typescript\n * import { planBackendMigration } from '@alneas/eaos-server/lifecycle-engine/backend-migration';\n * const plan = planBackendMigration({ migrationId: 'move-1', source: { id: 'old', databaseId: 'db-old', dialect: 'sqlite', mode: 'shared' }, target: { id: 'new', databaseId: 'db-new', dialect: 'postgres', mode: 'shared' }, scope: { kind: 'tenants', tenantIds: ['sample'] }, pluginIds: ['reports'], requestedAt: '2026-01-01T00:00:00Z', reason: 'Reviewed backend move' });\n * ```\n */\nexport function planBackendMigration(request: BackendMigrationRequest): BackendMigrationPlan {\n text(request?.migrationId, 'migrationId')\n text(request?.reason, 'reason', 1024)\n if (!Number.isFinite(Date.parse(request.requestedAt))) throw new Error('Invalid migration requestedAt')\n assertBackend(request.source, 'source backend')\n assertBackend(request.target, 'target backend')\n if (request.source.id === request.target.id || request.source.databaseId === request.target.databaseId) throw new Error('Backend migration requires a different physical database')\n if (!Array.isArray(request.pluginIds) || request.pluginIds.length === 0 || new Set(request.pluginIds).size !== request.pluginIds.length || request.pluginIds.some(id => !/^[a-zA-Z0-9][a-zA-Z0-9_-]{0,127}$/.test(id))) throw new Error('Invalid migration pluginIds')\n if (!request.scope || typeof request.scope !== 'object' || !['all-tenants', 'tenants'].includes(request.scope.kind)) throw new Error('Invalid migration scope')\n if (request.scope.kind === 'tenants' && (!Array.isArray(request.scope.tenantIds) || request.scope.tenantIds.length === 0 || new Set(request.scope.tenantIds).size !== request.scope.tenantIds.length || request.scope.tenantIds.some(id => !/^\\S{1,256}$/.test(id)))) throw new Error('Invalid migration tenant scope')\n const scope = request.scope.kind === 'all-tenants' ? request.scope : { kind: 'tenants' as const, tenantIds: [...request.scope.tenantIds].sort() }\n const scopedTenants = scope.kind === 'tenants' ? scope.tenantIds : null\n if (request.source.mode === 'dedicated' && (!scopedTenants || !scopedTenants.includes(request.source.tenantId!))) throw new Error('Migration scope does not include the dedicated source tenant')\n if (request.target.mode === 'dedicated' && (!scopedTenants || !scopedTenants.includes(request.target.tenantId!))) throw new Error('Migration scope does not include the dedicated target tenant')\n const normalized = structuredClone({ ...request, pluginIds: [...request.pluginIds].sort(), scope })\n const body = { format: 1 as const, request: normalized, phases: ['prepare', 'copy', 'verify', 'cutover', 'retain-source'] as const, requiresQuiesce: true as const, retainSourceData: true as const, destructiveOperations: false as const }\n return Object.freeze({ ...body, id: lifecycleDigest(body) })\n}\n\n/**\n * Checks that a reported migration verification matches its plan and contains only matched in-scope records.\n * @param plan - Reviewed backend migration plan.\n * @param report - Host report claiming passed verification for the plan's source and target.\n * @returns The original report when accepted; it is neither cloned nor independently measured.\n * @throws Error for mismatched identities, invalid timestamp/revisions, out-of-scope records or unpassed/unmatched evidence.\n * \n * @remarks\n * Validates nonempty records and nonnegative revisions, but does not prove exhaustive tenant/plugin coverage or equal source/target revision numbers. The host owns verification completeness and truth.\n * \n * @example\n * ```typescript\n * import { assertBackendMigrationVerification, type BackendMigrationPlan, type BackendMigrationVerificationReport } from '@alneas/eaos-server/lifecycle-engine/backend-migration';\n * export function inspectVerification(plan: BackendMigrationPlan, report: BackendMigrationVerificationReport) { return assertBackendMigrationVerification(plan, report); }\n * ```\n */\nexport function assertBackendMigrationVerification(plan: BackendMigrationPlan, report: BackendMigrationVerificationReport): BackendMigrationVerificationReport {\n if (!report || report.migrationId !== plan.request.migrationId || report.sourceBackendId !== plan.request.source.id || report.targetBackendId !== plan.request.target.id || !Number.isFinite(Date.parse(report.checkedAt)) || report.passed !== true || !Array.isArray(report.records) || report.records.length === 0) throw new Error('Backend migration verification is incomplete')\n const tenants = plan.request.scope.kind === 'tenants' ? new Set(plan.request.scope.tenantIds) : null\n for (const record of report.records) {\n if (!record || typeof record.tenantId !== 'string' || (tenants && !tenants.has(record.tenantId)) || !plan.request.pluginIds.includes(record.pluginId) || !Number.isSafeInteger(record.sourceRevision) || record.sourceRevision < 0 || !Number.isSafeInteger(record.targetRevision) || record.targetRevision < 0 || record.matched !== true) throw new Error('Backend migration verification is incomplete')\n }\n return report\n}\n\n/**\n * Validates matching verification and a source-retaining cutover receipt for the target backend.\n * @param plan - Reviewed backend migration plan.\n * @param report - Passed host verification matching the plan.\n * @param cutover - Host routing receipt with nonnegative routing revision and parseable cutover timestamp.\n * @returns The original cutover object; no routing mutation occurs.\n * @throws Error for invalid verification, mismatched target/migration, missing source-retention claim or invalid revision/time.\n * \n * @remarks\n * This is evidence shape validation, not independent copy verification or authority to switch a tenant.\n * \n * @example\n * ```typescript\n * import { assertBackendMigrationCutover, type BackendMigrationPlan, type BackendMigrationVerificationReport, type BackendMigrationCutover } from '@alneas/eaos-server/lifecycle-engine/backend-migration';\n * export function inspectCutover(plan: BackendMigrationPlan, report: BackendMigrationVerificationReport, receipt: BackendMigrationCutover) { return assertBackendMigrationCutover(plan, report, receipt); }\n * ```\n */\nexport function assertBackendMigrationCutover(plan: BackendMigrationPlan, report: BackendMigrationVerificationReport, cutover: BackendMigrationCutover): BackendMigrationCutover {\n assertBackendMigrationVerification(plan, report)\n if (!cutover || cutover.migrationId !== plan.request.migrationId || cutover.targetBackendId !== plan.request.target.id || cutover.sourceRetained !== true || !Number.isSafeInteger(cutover.routingRevision) || cutover.routingRevision < 0 || !Number.isFinite(Date.parse(cutover.cutoverAt))) throw new Error('Backend migration cutover is invalid')\n return cutover\n}\n"],"mappings":"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","names":["lt","valid","satisfies","id","dataContractTables","resolveDataContracts","id","m","digest","version","valid","lt","resolveDataContracts","key","installed","satisfies"]}
|