#!/usr/bin/env python3
import argparse
import base64
import hashlib
import json
import os
import re
import secrets
import shutil
import stat
import subprocess
import sys
import tarfile
import tempfile
import time
import urllib.error
import urllib.request
from datetime import datetime, timezone
from pathlib import Path, PurePosixPath


EXPECTED_SELF = Path("/usr/local/sbin/nodedc-deploy")
DEPLOY_ROOT = Path("/volume1/docker/nodedc-deploy")
INBOX = DEPLOY_ROOT / "inbox"
APPLIED_DIR = DEPLOY_ROOT / "applied"
FAILED_DIR = DEPLOY_ROOT / "failed"
BACKUPS_DIR = DEPLOY_ROOT / "backups"
STATE_DIR = DEPLOY_ROOT / "state"
TMP_DIR = DEPLOY_ROOT / ".tmp"
RUNTIME_DIR = DEPLOY_ROOT / "runtime"
STATE_FILE = STATE_DIR / "applied.jsonl"
FAILED_STATE_FILE = STATE_DIR / "failed.jsonl"
LOCK_DIR = STATE_DIR / "deploy.lock"
DOCKER = Path("/usr/local/bin/docker")
MAP_GATEWAY_SECRET_DIR = Path("/volume1/docker/nodedc-platform/secrets")
MAP_GATEWAY_SECRET_FILE = MAP_GATEWAY_SECRET_DIR / "map-gateway-admin-secret"
MAP_EGRESS_PROXY_SECRET_FILE = MAP_GATEWAY_SECRET_DIR / "map-egress-proxy-token"
PROXY_CONTUR_ENV_FILE = Path("/volume1/docker/proxy-contur/.env")
DC_AMD_PROXY_RUNTIME_DIR = Path("/volume1/docker/dc-amd-proxy/runtime")
DEVICE_PLANE_ROOT = Path("/volume1/docker/nodedc-device-plane")
DEVICE_PLANE_SECRET_DIR = DEVICE_PLANE_ROOT / "secrets"
DEVICE_PLANE_POSTGRES_PASSWORD_FILE = DEVICE_PLANE_SECRET_DIR / "postgres-password"
DEVICE_PLANE_GATEWAY_CORE_TOKEN_FILE = DEVICE_PLANE_SECRET_DIR / "gateway-core-token"
DEVICE_PLANE_IDENTIFIER_PEPPER_FILE = DEVICE_PLANE_SECRET_DIR / "identifier-pepper"
DEVICE_PLANE_CONTROL_CORE_IMAGE = "nodedc/device-control-core:local"
DEVICE_PLANE_GATEWAY_IMAGE = "nodedc/device-gateway:local"
DEVICE_PLANE_POSTGRES_BOOTSTRAP_REL = (
    "deployment/device-postgres-bootstrap-v1.json"
)
DEVICE_PLANE_POSTGRES_BOOTSTRAP_ENTRIES = (
    "docker-compose.device-plane.yml",
    DEVICE_PLANE_POSTGRES_BOOTSTRAP_REL,
)
DEVICE_PLANE_POSTGRES_VOLUME = "nodedc-device-plane-postgres-data"
EXTERNAL_DATA_PLANE_PROVISIONER_SECRET_DIR = MAP_GATEWAY_SECRET_DIR / "external-data-plane-provisioner"
EXTERNAL_DATA_PLANE_PROVISIONER_SECRET_FILE = EXTERNAL_DATA_PLANE_PROVISIONER_SECRET_DIR / "token"
ENGINE_CREDENTIAL_PROVISIONER_PRIVATE_KEY_FILE = EXTERNAL_DATA_PLANE_PROVISIONER_SECRET_DIR / "engine-credential-provisioner-ed25519.pem"
ENGINE_CREDENTIAL_SINK_STATE_DIR = Path("/volume2/nodedc-demo/nodedc-data/engine-credential-sink")
ENGINE_CREDENTIAL_SINK_PUBLIC_KEY_FILE = ENGINE_CREDENTIAL_SINK_STATE_DIR / "issuer-public-key.pem"
ENGINE_CREDENTIAL_PROVISIONER_KEY_ID = "engine-credential-provisioner-20260716-001"
ENGINE_CREDENTIAL_BACKEND_BASE_IMAGE = "node:20-alpine"
ENGINE_CREDENTIAL_BACKEND_IMAGE = "nodedc/engine-backend:credential-sink-20260716-001"
ENGINE_CREDENTIAL_BACKEND_PACKAGE_LOCK_SHA256 = "254f9086142eb469a0bcfcb393330a126e4d128a0df7455f0ac71d52b95e770b"
ENGINE_CREDENTIAL_BACKEND_NODE_MODULES_DIR = Path("/volume2/nodedc-demo/nodedc-backend-node_modules")
ENGINE_CREDENTIAL_BACKEND_OVERRIDE_TEMPLATE_REL = "nodedc-source/services/backend/credential-sink/docker-compose.immutable-runtime.yml"
ENGINE_CREDENTIAL_BACKEND_RUNTIME_DIR = RUNTIME_DIR / "engine-credential-sink"
ENGINE_CREDENTIAL_BACKEND_OVERRIDE_FILE = ENGINE_CREDENTIAL_BACKEND_RUNTIME_DIR / "docker-compose.immutable-runtime.yml"
ENGINE_CREDENTIAL_BACKEND_ROOTFS_FILE = ENGINE_CREDENTIAL_BACKEND_RUNTIME_DIR / "canonical-rootfs.tar"
ENGINE_CREDENTIAL_BACKEND_METADATA_FILE = ENGINE_CREDENTIAL_BACKEND_RUNTIME_DIR / "runtime-metadata.json"
ENGINE_CREDENTIAL_BACKEND_ACTIVATION_FILE = ENGINE_CREDENTIAL_BACKEND_RUNTIME_DIR / "activation.ready"
ENGINE_DATA_PRODUCT_PUBLISH_GRANT_OVERRIDE_REL = "nodedc-source/services/backend/data-product-publish-grant/docker-compose.immutable-runtime.yml"
ENGINE_DATA_PRODUCT_READ_GRANT_OVERRIDE_REL = "nodedc-source/services/backend/data-product-read-grant/docker-compose.immutable-runtime.yml"
ENGINE_AGENT_FULL_GRANT_MIGRATION_STORE_REL = "nodedc-source/server/engineAgents/store.js"
ENGINE_AGENT_FULL_GRANT_MIGRATION_PREDECESSOR_SHA256 = "52daa43499d6d9a97fe7ffa891edb9212b7791e733f91dd3ca686d42739b7e9a"
ENGINE_AGENT_FULL_GRANT_MIGRATION_TARGET_SHA256 = "2e62654c2dc12905efcc83a9dff45a818dd7b47924a10600160835c4416540e9"
ENGINE_DATA_PRODUCT_PUBLISH_GRANT_PREDECESSOR_COMPOSE_SHA256 = "258cebb64ff1943c939655cc55bdce00fc5c4dced67ec291d84d6df066ace50e"
ENGINE_EDP_MANAGED_PROVISIONER_SECRET_DIR = MAP_GATEWAY_SECRET_DIR / "engine-edp-managed-provisioner"
ENGINE_EDP_MANAGED_PROVISIONER_PRIVATE_KEY_FILE = ENGINE_EDP_MANAGED_PROVISIONER_SECRET_DIR / "private-key.pem"
ENGINE_EDP_MANAGED_PROVISIONER_TRUST_DIR = Path("/volume1/docker/nodedc-platform/trust/engine-managed-provisioner")
ENGINE_EDP_MANAGED_PROVISIONER_PUBLIC_KEY_FILE = ENGINE_EDP_MANAGED_PROVISIONER_TRUST_DIR / "public-key.pem"
FOUNDRY_EDP_MANAGED_PROVISIONER_SECRET_DIR = MAP_GATEWAY_SECRET_DIR / "foundry-edp-managed-provisioner"
FOUNDRY_EDP_MANAGED_PROVISIONER_PRIVATE_KEY_FILE = FOUNDRY_EDP_MANAGED_PROVISIONER_SECRET_DIR / "private-key.pem"
FOUNDRY_EDP_MANAGED_PROVISIONER_TRUST_DIR = Path("/volume1/docker/nodedc-platform/trust/foundry-managed-provisioner")
FOUNDRY_EDP_MANAGED_PROVISIONER_PUBLIC_KEY_FILE = FOUNDRY_EDP_MANAGED_PROVISIONER_TRUST_DIR / "public-key.pem"
EXTERNAL_DATA_PLANE_READER_GRANTS_DIR = MAP_GATEWAY_SECRET_DIR / "external-data-plane-reader-grants"
FOUNDRY_BINDING_GRANTS_DIR = MAP_GATEWAY_SECRET_DIR / "foundry-binding-grants"
N8N_PRIVATE_EXTENSION_RELEASES_ROOT = Path("/volume1/docker/nodedc-platform/n8n-private-extensions")
ENGINE_N8N_SEALED_RELEASES_ROOT = Path("/volume2/nodedc-demo/n8n-private-extensions")
ENGINE_N8N_TRANSITION_DESCRIPTOR_REL = "nodedc-source/services/n8n/private-extensions/ndc-activation.json"
ENGINE_N8N_COMPOSE_OVERRIDE_REL = "nodedc-source/services/n8n/private-extensions/docker-compose.ndc-private-extension.yml"
ENGINE_N8N_SCHEMA_ROOT_REL = "nodedc-source/server/assets/n8n/schema/v2.3.2"
ENGINE_N8N_NODES_CATALOG_REL = f"{ENGINE_N8N_SCHEMA_ROOT_REL}/nodes.catalog.json"
ENGINE_N8N_CREDENTIALS_CATALOG_REL = f"{ENGINE_N8N_SCHEMA_ROOT_REL}/credentials.catalog.json"
ENGINE_N8N_SCHEMA_META_REL = f"{ENGINE_N8N_SCHEMA_ROOT_REL}/meta.json"
ENGINE_N8N_ICON_REL = "nodedc-source/server/assets/n8n/icons/ndc.svg"
ENGINE_N8N_DARK_ICON_REL = "nodedc-source/server/assets/n8n/icons/ndc.dark.svg"
ENGINE_NODE_INTELLIGENCE_RELEASE_ID = "2.33.2-974a9fb3492f"
ENGINE_NODE_INTELLIGENCE_UPSTREAM_COMMIT = "974a9fb3492fe2c4984ee0549085d531cdc6242a"
ENGINE_NODE_INTELLIGENCE_IMAGE = (
    f"nodedc/engine-node-intelligence:{ENGINE_NODE_INTELLIGENCE_RELEASE_ID}"
)
ENGINE_NODE_INTELLIGENCE_SERVICE = "nodedc-node-intelligence"
ENGINE_NODE_INTELLIGENCE_RUNTIME_UID = 11007
ENGINE_NODE_INTELLIGENCE_RUNTIME_GID = 11007
ENGINE_NODE_INTELLIGENCE_RUNTIME_DIR = RUNTIME_DIR / "engine-node-intelligence"
ENGINE_NODE_INTELLIGENCE_SECRET_FILE = ENGINE_NODE_INTELLIGENCE_RUNTIME_DIR / "auth-token"
ENGINE_NODE_INTELLIGENCE_RELEASES_DIR = ENGINE_NODE_INTELLIGENCE_RUNTIME_DIR / "releases"
ENGINE_NODE_INTELLIGENCE_SECRET_CONTAINER_PATH = (
    "/run/nodedc-secrets/engine-node-intelligence-auth-token"
)
ENGINE_NODE_INTELLIGENCE_SOURCE_REL = "nodedc-source/server/nodeIntelligence"
ENGINE_NODE_INTELLIGENCE_GATEWAY_REL = "nodedc-source/server/routes/engineAgentGateway.js"
ENGINE_NODE_INTELLIGENCE_SERVICE_ROOT_REL = "nodedc-source/services/node-intelligence"
ENGINE_NODE_INTELLIGENCE_OVERRIDE_REL = (
    f"{ENGINE_NODE_INTELLIGENCE_SERVICE_ROOT_REL}/docker-compose.immutable-runtime.yml"
)
ENGINE_NODE_INTELLIGENCE_DESCRIPTOR_REL = (
    f"{ENGINE_NODE_INTELLIGENCE_SERVICE_ROOT_REL}/activation.json"
)
ENGINE_NODE_INTELLIGENCE_IMAGE_ARCHIVE_REL = (
    f"{ENGINE_NODE_INTELLIGENCE_SERVICE_ROOT_REL}/image/engine-node-intelligence.tar"
)
ENGINE_NODE_INTELLIGENCE_PREDECESSOR_GATEWAY_SHA256 = (
    "6b8c80fa997ef7c438d199a6ee942c5e37aebc4057667af417897fa636131db4"
)
ENGINE_NODE_INTELLIGENCE_PREDECESSOR_COMPOSE_SHA256 = (
    "258cebb64ff1943c939655cc55bdce00fc5c4dced67ec291d84d6df066ace50e"
)
ENGINE_NODE_INTELLIGENCE_ARTIFACT_ENTRIES = (
    ENGINE_NODE_INTELLIGENCE_SOURCE_REL,
    ENGINE_NODE_INTELLIGENCE_GATEWAY_REL,
    ENGINE_NODE_INTELLIGENCE_SERVICE_ROOT_REL,
)
ENGINE_NODE_INTELLIGENCE_ROLLBACK_ENTRIES = (
    ENGINE_NODE_INTELLIGENCE_GATEWAY_REL,
    ENGINE_NODE_INTELLIGENCE_SERVICE_ROOT_REL,
)
ENGINE_MCP_CONTROL_PLANE_DESCRIPTOR_REL = ENGINE_NODE_INTELLIGENCE_DESCRIPTOR_REL
ENGINE_MCP_CONTROL_PLANE_ARTIFACT_ENTRIES = (
    "nodedc-source/server/assets/engine-agent-npm/bin/nodedc-engine-codex-agent.mjs",
    "nodedc-source/server/assets/engine-agent-npm/package.json",
    "nodedc-source/server/assets/nodedc-engine-codex-agent-0.1.4.tgz",
    "nodedc-source/server/dataProductPublishGrant/providerCatalog.js",
    "nodedc-source/server/dataProductPublishGrant/signedDataPlaneClient.js",
    "nodedc-source/server/dataProductReadGrant/acceptance.js",
    "nodedc-source/server/dataProductReadGrant/service.js",
    "nodedc-source/server/dataProductReadGrant/store.js",
    "nodedc-source/server/engineAgents/store.js",
    "nodedc-source/server/nodeIntelligence/upstreamProjection.js",
    ENGINE_NODE_INTELLIGENCE_GATEWAY_REL,
    "nodedc-source/server/routes/n8n.js",
    "nodedc-source/server/routes/ndcAgentMcp.js",
    ENGINE_DATA_PRODUCT_READ_GRANT_OVERRIDE_REL,
    "nodedc-source/server/dataProductPublishGrant/service.js",
    "nodedc-source/server/dataProductPublishGrant/store.js",
    ENGINE_MCP_CONTROL_PLANE_DESCRIPTOR_REL,
)
ENGINE_MCP_CONTROL_PLANE_PREDECESSOR_SHA256 = {
    ENGINE_NODE_INTELLIGENCE_GATEWAY_REL: "604a75ad3b9b463cea5e578760c8a23592e2e00b8acfc0099730a347e27bf4e8",
    "nodedc-source/server/routes/ndcAgentMcp.js": "534e2c85e1faecc72a00da7ad32d0584ee09b6bd89eeec2221c3b23d80e1e962",
    "nodedc-source/server/routes/n8n.js": "de6e3c76740af86e2eaeedede140b5ee54eb526f03db270324d7a4fe513f6817",
    "nodedc-source/server/dataProductPublishGrant/providerCatalog.js": "a96d3695fdb3ed7012b9041182f37b09e32d1dfa0dbb391d8db2d7d25a39d64d",
    "nodedc-source/server/dataProductPublishGrant/signedDataPlaneClient.js": "1a26728ac69c5ef3fdce1ce1154a6ce330f72286b6e07825796a246070d15bbf",
    "nodedc-source/server/engineAgents/store.js": "2e62654c2dc12905efcc83a9dff45a818dd7b47924a10600160835c4416540e9",
    "nodedc-source/server/nodeIntelligence/upstreamProjection.js": "946353ed8582c5d96e08361603425cc45eaf231f730ae46a75028d3bef352ee9",
    "nodedc-source/server/assets/engine-agent-npm/bin/nodedc-engine-codex-agent.mjs": "7d3d7a9bc48614e6cd238199caa384073096b7ec8273703833681151b464ef17",
    "nodedc-source/server/assets/engine-agent-npm/package.json": "9f299b20db4855b1bb4a9bd2e1095dfd059cd90ec82e936884a380aa41249e28",
    "nodedc-source/server/dataProductPublishGrant/service.js": "85ded82d707e0ef5b1ad739b5a9be24c1432e2dd9e5051108739f09daf20f47c",
    "nodedc-source/server/dataProductPublishGrant/store.js": "ef2a5e6bfad9f0b1710db006a0d30d01cd9bcaf06524b0e9f975dd771efe3952",
}
ENGINE_MCP_CONTROL_PLANE_TARGET_SHA256 = {
    ENGINE_NODE_INTELLIGENCE_GATEWAY_REL: "96c726dab5cf1341f74e6e1095d518058ca320e0dd5738e25bdbe75db1f4fc15",
    "nodedc-source/server/routes/ndcAgentMcp.js": "534e2c85e1faecc72a00da7ad32d0584ee09b6bd89eeec2221c3b23d80e1e962",
    "nodedc-source/server/routes/n8n.js": "f293a7794405badbabd2bf7ef088f96fe1167d9e249f05cbfc8af280a0d3e8f8",
    "nodedc-source/server/dataProductPublishGrant/providerCatalog.js": "901b8fad80018ce177b34ced804b39cb140a47e831414057f484296b373c651d",
    "nodedc-source/server/dataProductPublishGrant/signedDataPlaneClient.js": "c2a13d5eb49937fe70ec6451d0465cac54c19c7fae44448db099079473ec02fc",
    "nodedc-source/server/dataProductReadGrant/acceptance.js": "202dbe575b2f2e1c584aa7e6e99e38fa84f12496feb454e3dbd3f98e2d0396dd",
    "nodedc-source/server/dataProductReadGrant/service.js": "65b8cdd6b603333bac1feb303e9791feb1e9da39dc9b5bfc3df3961273b0052e",
    "nodedc-source/server/dataProductReadGrant/store.js": "c3fcdc59a794f57d92e3d2ac713ee28341347cebd25364c4060beaa3dc2151de",
    "nodedc-source/server/engineAgents/store.js": "debd351fe0b8c72b33b8c79909b8f339cbaf061b970576f3ae72df52ebaa211f",
    "nodedc-source/server/nodeIntelligence/upstreamProjection.js": "761a874b102a938bc6018159ddacdaac71ad6ae08e9f0f8d7f3b58a0165a5131",
    "nodedc-source/server/assets/engine-agent-npm/bin/nodedc-engine-codex-agent.mjs": "521098de69fe288a56bd4158c849c1055ba24be08e19f7a4111618d0e8138445",
    "nodedc-source/server/assets/engine-agent-npm/package.json": "cbe113e9b10bb84b9ccbffa3e261908e58a8430c11abe2cf4fd5304741b04597",
    "nodedc-source/server/assets/nodedc-engine-codex-agent-0.1.4.tgz": "e74c0136d346f904b42589d75cb11a952b4d2f21153f1b057fba28e9acf4f95f",
    ENGINE_DATA_PRODUCT_READ_GRANT_OVERRIDE_REL: "952df0cb2ac477e644f5f3a9d64b4872ce1da33356eeab0bec17dcb2931cf653",
    "nodedc-source/server/dataProductPublishGrant/service.js": "ded3832c9677345a988448ae8e69cef254fd9bf39d2de20cffa295c1feedcd7c",
    "nodedc-source/server/dataProductPublishGrant/store.js": "a92303b2732e21f68c1ac732fa26e4983cbadf3515741cee983b916a283d754c",
}
ENGINE_MCP_CONTROL_PLANE_NEW_PATHS = (
    "nodedc-source/server/assets/nodedc-engine-codex-agent-0.1.4.tgz",
    "nodedc-source/server/dataProductReadGrant/acceptance.js",
    "nodedc-source/server/dataProductReadGrant/service.js",
    "nodedc-source/server/dataProductReadGrant/store.js",
    ENGINE_DATA_PRODUCT_READ_GRANT_OVERRIDE_REL,
)
ENGINE_MCP_ONTOLOGY_SDK_ARTIFACT_ENTRIES = (
    "nodedc-source/server/assets/engine-agent-npm/bin/nodedc-engine-codex-agent.mjs",
    "nodedc-source/server/assets/engine-agent-npm/package.json",
    "nodedc-source/server/assets/nodedc-engine-codex-agent-0.1.5.tgz",
    "nodedc-source/server/assets/provider-packages/v1/catalog.json",
    "nodedc-source/server/dataProductPublishGrant/providerCatalog.js",
    "nodedc-source/server/engineAgents/store.js",
    ENGINE_NODE_INTELLIGENCE_GATEWAY_REL,
    ENGINE_MCP_CONTROL_PLANE_DESCRIPTOR_REL,
)
ENGINE_MCP_ONTOLOGY_SDK_PREDECESSOR_SHA256 = {
    "nodedc-source/server/assets/engine-agent-npm/bin/nodedc-engine-codex-agent.mjs": "521098de69fe288a56bd4158c849c1055ba24be08e19f7a4111618d0e8138445",
    "nodedc-source/server/assets/engine-agent-npm/package.json": "cbe113e9b10bb84b9ccbffa3e261908e58a8430c11abe2cf4fd5304741b04597",
    "nodedc-source/server/assets/provider-packages/v1/catalog.json": "30f89052b6557a2444550bd6e7eed30747b2d9b7ff3a22d079d9905fe0a04702",
    "nodedc-source/server/dataProductPublishGrant/providerCatalog.js": "901b8fad80018ce177b34ced804b39cb140a47e831414057f484296b373c651d",
    "nodedc-source/server/engineAgents/store.js": "debd351fe0b8c72b33b8c79909b8f339cbaf061b970576f3ae72df52ebaa211f",
    ENGINE_NODE_INTELLIGENCE_GATEWAY_REL: "96c726dab5cf1341f74e6e1095d518058ca320e0dd5738e25bdbe75db1f4fc15",
}
ENGINE_MCP_ONTOLOGY_SDK_TARGET_SHA256 = {
    "nodedc-source/server/assets/engine-agent-npm/bin/nodedc-engine-codex-agent.mjs": "adff3e474c914680f7d36b204d1dc03e69dc8065fff1f80b6713526cfc970137",
    "nodedc-source/server/assets/engine-agent-npm/package.json": "0741647e4f7f58f69f3021d367484609a8e1eb7b8727d6ad9639bd9906b7f455",
    "nodedc-source/server/assets/nodedc-engine-codex-agent-0.1.5.tgz": "72a1b2d41a12a298eaae63ba3334c7c66b6ca53de6a3f03a48607d4ff6da42fb",
    "nodedc-source/server/assets/provider-packages/v1/catalog.json": "4800e1a1c2af5e4893b1a403c04e91f55689383457caff833edc9e35e8e7e37a",
    "nodedc-source/server/dataProductPublishGrant/providerCatalog.js": "d5511a8bd3b4238af88a89537661c9ca4c0126bca7b5ad225985e27ccdb2c64c",
    "nodedc-source/server/engineAgents/store.js": "4cd4bdd5958cfafee184e98a04fe12aa0c1cbe884326beaec63c99f9fff61285",
    ENGINE_NODE_INTELLIGENCE_GATEWAY_REL: "25fa013ddbfd7d0c7ece8c792daec5f345062757c85eb56cfbff45bf1e812152",
}
ENGINE_MCP_ONTOLOGY_SDK_NEW_PATHS = (
    "nodedc-source/server/assets/nodedc-engine-codex-agent-0.1.5.tgz",
)
ENGINE_MCP_AUTONOMY_PROVIDER_V5_ARTIFACT_ENTRIES = (
    "nodedc-source/server/assets/engine-agent-npm/bin/nodedc-engine-codex-agent.mjs",
    "nodedc-source/server/assets/engine-agent-npm/package.json",
    "nodedc-source/server/assets/nodedc-engine-codex-agent-0.1.6.tgz",
    "nodedc-source/server/assets/provider-packages/v1/catalog.json",
    "nodedc-source/server/engineAgents/store.js",
    ENGINE_NODE_INTELLIGENCE_GATEWAY_REL,
    ENGINE_MCP_CONTROL_PLANE_DESCRIPTOR_REL,
)
ENGINE_MCP_AUTONOMY_PROVIDER_V5_PREDECESSOR_SHA256 = {
    "nodedc-source/server/assets/engine-agent-npm/bin/nodedc-engine-codex-agent.mjs": "521098de69fe288a56bd4158c849c1055ba24be08e19f7a4111618d0e8138445",
    "nodedc-source/server/assets/engine-agent-npm/package.json": "cbe113e9b10bb84b9ccbffa3e261908e58a8430c11abe2cf4fd5304741b04597",
    "nodedc-source/server/assets/provider-packages/v1/catalog.json": "17f3e368f3264cbbd708965c9e1fd735aa974f15a1383bf88cd6d14a43dbf32d",
    "nodedc-source/server/engineAgents/store.js": "debd351fe0b8c72b33b8c79909b8f339cbaf061b970576f3ae72df52ebaa211f",
    ENGINE_NODE_INTELLIGENCE_GATEWAY_REL: "96c726dab5cf1341f74e6e1095d518058ca320e0dd5738e25bdbe75db1f4fc15",
}
ENGINE_MCP_AUTONOMY_PROVIDER_V5_TARGET_SHA256 = {
    "nodedc-source/server/assets/engine-agent-npm/bin/nodedc-engine-codex-agent.mjs": "c15c9da4f90f44a4e9e12f3683127e906d614fb98e562faa0c939505c973e074",
    "nodedc-source/server/assets/engine-agent-npm/package.json": "2ca8dcab0fa04bb1b21add1f75a9be61d5aa97753443ee1917302b4e0da5780a",
    "nodedc-source/server/assets/nodedc-engine-codex-agent-0.1.6.tgz": "d007a81cb4e4af569b3c54d3869b0f60b5597e3b531bff232145fa1851d8572a",
    "nodedc-source/server/assets/provider-packages/v1/catalog.json": "63e0741646197f0b1b3c64a4095e1bc8fb3a95ee6caf20b0293f89d869c9e620",
    "nodedc-source/server/engineAgents/store.js": "4cd4bdd5958cfafee184e98a04fe12aa0c1cbe884326beaec63c99f9fff61285",
    ENGINE_NODE_INTELLIGENCE_GATEWAY_REL: "5331f6dc8dc306f641370a2968eb025ee3e278e27ae9a217e4cfc2901fec369c",
}
ENGINE_MCP_AUTONOMY_PROVIDER_V5_NEW_PATHS = (
    "nodedc-source/server/assets/nodedc-engine-codex-agent-0.1.6.tgz",
)
ENGINE_L2_CLOSED_LOOP_DESCRIPTOR_REL = ENGINE_NODE_INTELLIGENCE_DESCRIPTOR_REL
ENGINE_L2_CLOSED_LOOP_ARTIFACT_ENTRIES = (
    "nodedc-source/server/index.js",
    "nodedc-source/server/l2/graphRepository.js",
    "nodedc-source/server/realtime/ws.js",
    ENGINE_NODE_INTELLIGENCE_GATEWAY_REL,
    "nodedc-source/server/routes/n8n.js",
    "nodedc-source/server/routes/ndcAgentMcp.js",
    "nodedc-source/src/App.tsx",
    "nodedc-source/src/n8n/N8nSubworkflowHost.tsx",
    "nodedc-source/src/realtime/useMultiplayer.ts",
    "nodedc-source/src/utils/n8nApi.ts",
    "nodedc-source/dist/index.html",
    "nodedc-source/dist/assets",
    ENGINE_L2_CLOSED_LOOP_DESCRIPTOR_REL,
)
ENGINE_L2_CLOSED_LOOP_PARTIAL_SHA256 = {
    "nodedc-source/server/index.js": "1896e1cade61579863c50ff3f52f2e81ff27f2a511a9d362db81925ee21cefad",
    "nodedc-source/server/l2/graphRepository.js": "94ad08e1bb7e7be04854f1f911e06ee1acd6e09631f33f4c01e42e230665ac33",
    "nodedc-source/server/realtime/ws.js": "82cfa833e05c2fc6d6049dd4564af06164b5c784fdfb82c243ca67519f4509c2",
    ENGINE_NODE_INTELLIGENCE_GATEWAY_REL: "4f600a2781be9118bec891fa2a6f20d7f55e0892ef2f06af24059193cebd28f4",
    "nodedc-source/server/routes/n8n.js": "752cb1524160adc1c95163c34e139b615c063d2ce8980f2a63879bddbd0f1e08",
    "nodedc-source/server/routes/ndcAgentMcp.js": "353a10291ceb93c3641ece60ec6e809a394be86f5ceb97cb44755178940409dd",
    "nodedc-source/src/App.tsx": "b3e61a89330b774f309660208d05143d299ab582f18765c1c14e2122a62c4d5e",
    "nodedc-source/src/n8n/N8nSubworkflowHost.tsx": "683aa44ba92aeac4879889e2bdb5319282976d7680d620701578830ce9677087",
    "nodedc-source/src/realtime/useMultiplayer.ts": "a4d001d9914098e50a78d8abe0a66344d23680b7a19b3573aa7b6f48c8bb9c35",
    "nodedc-source/src/utils/n8nApi.ts": "6f16d4992c51ffcc1e71a7bd172fd9ceb440d6e1a74d69ef1db62e0ac4230b3c",
    "nodedc-source/dist/index.html": "90d72f8790dc8cf951066b1210447c84d640373117bae23f3a4cb3227fb96d6d",
    "nodedc-source/dist/assets/index-Bim2pv1P.css": "18322addd45c126a7b8396f36b005f3085fddba3e9b346dd2c910f6fa6987ebf",
    "nodedc-source/dist/assets/index-CqvJfRRS.js": "06e6c23b03ea2ba8a4890e1f1714fd08ebaf18d735834200af6ab430af360ca8",
    ENGINE_L2_CLOSED_LOOP_DESCRIPTOR_REL: "84b0e15a10cedf334ad04d6f31c908da2dc155503c9974f0eeb75b01e20fb884",
}
ENGINE_L2_CLOSED_LOOP_TARGET_SHA256 = {
    **ENGINE_L2_CLOSED_LOOP_PARTIAL_SHA256,
    ENGINE_L2_CLOSED_LOOP_DESCRIPTOR_REL: "63e7619c6971d02102583bb5d80d33ece293b952f113200fa0b76f0e88c2dd32",
}
ENGINE_L2_CLOSED_LOOP_STABLE_SHA256 = {
    "nodedc-source/server/index.js": "0ac408e0e9a7bc5c8e13a00afc957b982b065e2bc414919839e0b0a11aa05ba4",
    "nodedc-source/server/realtime/ws.js": "340437ee2c6cc06c41b1e47f8b1ada24b68e175bb6fc4c361398bef00dd89686",
    ENGINE_NODE_INTELLIGENCE_GATEWAY_REL: "5331f6dc8dc306f641370a2968eb025ee3e278e27ae9a217e4cfc2901fec369c",
    "nodedc-source/server/routes/n8n.js": "9bc3638e271102abec91bb80413329befb89d60c0e4dc0548f0dd11e93220d0a",
    "nodedc-source/server/routes/ndcAgentMcp.js": "534e2c85e1faecc72a00da7ad32d0584ee09b6bd89eeec2221c3b23d80e1e962",
    "nodedc-source/src/App.tsx": "d9bc0f23ceaaf4f5534ac9a9b1f97d84fd8eee4679c59b5999b5a75b8c77bb32",
    "nodedc-source/src/n8n/N8nSubworkflowHost.tsx": "306694f329670a64322651ad249b057a74b34dace82d68d4071a365636d91d71",
    "nodedc-source/src/realtime/useMultiplayer.ts": "3d8f150037d994dc8739fa9f6696acfe874c45128e567a6090cc4996b76f9e9d",
    "nodedc-source/src/utils/n8nApi.ts": "2d10acda54d8c10637008612af9e3ad7625bd7fe17e9cfa38aa45c340eb171eb",
    "nodedc-source/dist/index.html": "8894f62ad590168862e81266bc4602410279634b666af72cb14ad80aeb71ea74",
    "nodedc-source/dist/assets/index-4TenBzkg.js": "a48fcacf3348c20a432cd6da2627b89c0c3e54bc989c727b620125dd3412538a",
    "nodedc-source/dist/assets/index-BQ3RBHy9.js": "6e0f4c841afe3e0beb398943af915c8ee5d4a7df0b77b92e277e66faa3fa26a8",
    "nodedc-source/dist/assets/index-Bim2pv1P.css": "18322addd45c126a7b8396f36b005f3085fddba3e9b346dd2c910f6fa6987ebf",
    "nodedc-source/dist/assets/index-DJ1CMfu4.js": "a0aaf72d2ed390142ff2ea03dbcfdd534637e5faefd80d8aa7d705a804abe065",
    ENGINE_L2_CLOSED_LOOP_DESCRIPTOR_REL: "84b0e15a10cedf334ad04d6f31c908da2dc155503c9974f0eeb75b01e20fb884",
}
ENGINE_L2_CLOSED_LOOP_FAILED_PATCH_ID = "engine-l2-closed-loop-20260723-030"
ENGINE_L2_CLOSED_LOOP_FAILED_ARTIFACT = (
    "nodedc-engine-l2-closed-loop-20260723-030.tgz.20260723-123228"
)
ENGINE_L2_CLOSED_LOOP_FAILED_ARTIFACT_SHA256 = (
    "4c8401fcb1d318c52933cc3327015e9e4cbaaa5c38f1b45856acec2c72efdd2e"
)
ENGINE_L2_CLOSED_LOOP_RECOVERY_BACKUP_ID = (
    "engine-engine-l2-closed-loop-20260723-030-20260723-123228"
)
ENGINE_L2_CLOSED_LOOP_RECOVERY_BACKUP_SHA256 = {
    "manifest.env": "7cf2a04c64f62547d408613307f7880bf350b9d305306af0e4eb8b81cfaa73bc",
    "files.txt": "c4d2e0395b8ff076b648bd348283e4113feecf50b056ba6d1f495bafe4d09f27",
    "source-before.tgz": "056d9400d52eeda7a51d225a803ab4d3465e06541d6646b4b728296a21c08ec5",
    "existing-files.txt": "4c5de3d062d96b398dcaf44a6dde20c168ca0efd263893d51ce1fc545c59b8f8",
    "missing-files.txt": "16d708945792cb35fcbe11d2c23a146e489fb183c4f498496ef40a97090c6008",
}
ENGINE_PROVIDER_SECURITY_CATALOG_REL = (
    "nodedc-source/server/assets/provider-packages/v1/catalog.json"
)
ENGINE_PROVIDER_SECURITY_CATALOG_ARTIFACT_ENTRIES = (
    ENGINE_PROVIDER_SECURITY_CATALOG_REL,
)
ENGINE_PROVIDER_SECURITY_CATALOG_PREDECESSOR_SHA256 = (
    "dd67d8b01091072a4e7be3820b9639c12f2f897ccbbd79208123564d10c1cd81"
)
ENGINE_PROVIDER_SECURITY_CATALOG_TARGET_SHA256 = (
    "773335bb616a5c03eb2108c4f53ef092c02e75ee75f014511201bc12e2956b27"
)
ENGINE_CONTROL_PLANE_STATE_REL = "nodedc-control-plane"
ENGINE_PUBLISH_GRANT_STATE_REL = f"{ENGINE_CONTROL_PLANE_STATE_REL}/publish-grants"
ENGINE_READ_GRANT_STATE_REL = f"{ENGINE_CONTROL_PLANE_STATE_REL}/read-grants"
ENGINE_CONTROL_PLANE_STATE_PATH = Path("/volume2/nodedc-demo/nodedc-control-plane")
ENGINE_PUBLISH_GRANT_STATE_PATH = ENGINE_CONTROL_PLANE_STATE_PATH / "publish-grants"
ENGINE_READ_GRANT_STATE_PATH = ENGINE_CONTROL_PLANE_STATE_PATH / "read-grants"
ENGINE_EDP_PRIVATE_KEY_CONTAINER_PATH = "/run/nodedc-secrets/engine-edp-managed-provisioner-private.pem"
ENGINE_CONTROL_PLANE_CONTAINER_PATH = "/var/lib/nodedc-control-plane"
ENGINE_PUBLISH_GRANT_CONTAINER_PATH = "/var/lib/nodedc-control-plane/publish-grants"
ENGINE_READ_GRANT_CONTAINER_PATH = "/var/lib/nodedc-control-plane/read-grants"
EXTERNAL_DATA_PLANE_MANAGED_TRUST_CONTAINER_PATH = "/run/nodedc-trust/engine-managed-provisioner"
EXTERNAL_DATA_PLANE_INTERNAL_URL = "http://external-data-plane:18106"
PLATFORM_EXTERNAL_DATA_PLANE_COMPOSE_REL = "platform/docker-compose.external-data-plane.yml"
EXTERNAL_DATA_PLANE_DATABASE_SERVICE = "external-data-plane-postgres"
EXTERNAL_DATA_PLANE_SERVICE = "external-data-plane"
EXTERNAL_DATA_PLANE_IMAGE = "nodedc/external-data-plane:local"
ENGINE_N8N_VERSION = "2.3.2"
ENGINE_N8N_BASE_IMAGE = "docker.n8n.io/n8nio/n8n:2.3.2"
ENGINE_N8N_BASE_ARCHITECTURE = "amd64"
ENGINE_N8N_RUNTIME_PACKAGE_PATH = "/home/node/.n8n/nodes/node_modules/n8n-nodes-ndc"
ENGINE_N8N_NODE_MODULES_PATH = "/usr/local/lib/node_modules/n8n/node_modules"
ENGINE_N8N_ICON_SHA256 = "1c928fc996d8b82121e8f8e327d74b1dd21556c106de99c5e8d317d926c0ba17"
ENGINE_N8N_DARK_ICON_SHA256 = "ef3b8551da4ce04527736405afa9a220a2c76d047bd18f6f7124b9adb4216b0c"
ENGINE_N8N_RELEASE_CATALOG_JSON_SHA256 = {
    "0.1.2-05e4b38b14b4a019": {
        "nodes": "230f712230f7ee8debaa4b44a4358cc19c205bc43305d8ed89d5e3daac466506",
        "credentials": "a26824ffc0e15db857c792153de3417febc0dbba4880380d6c8cd544b3c80f4d",
        "meta": "caf7635420c61333e65f68350f5567217aed96fb51354b38764bcac2c24e7966",
    },
    "0.1.3-3354149b5245e39a": {
        "nodes": "b0a5215699a6e691b8cfc505ab457d5632ef6d83adb3537520d0b60760ba16b2",
        "credentials": "a26824ffc0e15db857c792153de3417febc0dbba4880380d6c8cd544b3c80f4d",
        "meta": "b8aa60c0d919573626fa0694a1e4ae9ede015325a5d312e3e05d5ac293084aa7",
    },
    "0.1.4-59dc9f7882721d6a": {
        "nodes": "b0a5215699a6e691b8cfc505ab457d5632ef6d83adb3537520d0b60760ba16b2",
        "credentials": "af8ada839070a4c24b9b10981a751c2b2db651dced1392333d7a4ef13de4564e",
        "meta": "8fadbc594c5d14b1d53ab69b677f00823949410b9a37f4e43ecc321e89d68983",
    },
    "0.1.5-3c8ae53f010d7c88": {
        "nodes": "fb2ef4d38b9c071fae117a27381714658a1a19334b82fc79d64d13f27555fe5a",
        "credentials": "af8ada839070a4c24b9b10981a751c2b2db651dced1392333d7a4ef13de4564e",
        "meta": "b324592c38d518af8320d8540c7061e4684056ae88a676cf5e50c6eef03c0dd7",
    },
    "0.1.6-25cc2d7a52a0d0ee": {
        "nodes": "fb2ef4d38b9c071fae117a27381714658a1a19334b82fc79d64d13f27555fe5a",
        "credentials": "af8ada839070a4c24b9b10981a751c2b2db651dced1392333d7a4ef13de4564e",
        "meta": "58adcb182e5f231a4798636a99887a1f214e3c6e1eb4c0dc2d9b2f3aa80a99ef",
    },
}
ENGINE_N8N_INACTIVE_NODES_CATALOG_JSON_SHA256 = "b70d9d8130d498c55de46a5d0758c844f1242b70803457b2291ab3a9de8056f2"
ENGINE_N8N_INACTIVE_CREDENTIALS_CATALOG_JSON_SHA256 = "680e9f52aac791efbd38e3bd99bd51ef5cded9756d867897c6c2755850e87b50"
ENGINE_N8N_INACTIVE_META_JSON_SHA256 = "0ac555d7ab31cb0ca042db4f474e83cfefbf20b5bbb2e1509fead27ed21e8acb"
MAP_GATEWAY_RUNTIME_GID = 1000
EXTERNAL_DATA_PLANE_RUNTIME_UID = 11006
EXTERNAL_DATA_PLANE_RUNTIME_GID = 11006

MAX_ARTIFACT_BYTES = 512 * 1024 * 1024
MAX_MEMBER_COUNT = 20000
MAX_PAYLOAD_BYTES = 1024 * 1024 * 1024
MAX_FILE_BYTES = 256 * 1024 * 1024

PATCH_ID_RE = re.compile(r"^[A-Za-z0-9._-]{1,96}$")
MANIFEST_KEYS = {"id", "component", "type"}
MAP_GATEWAY_SECRET_RE = re.compile(r"^[A-Za-z0-9_-]{48,256}$")
EXTERNAL_DATA_PLANE_PROVISIONER_SECRET_RE = re.compile(r"^[A-Za-z0-9_-]{48,256}$")
ENGINE_NODE_INTELLIGENCE_SECRET_RE = re.compile(r"^[A-Za-z0-9_-]{48,256}$")
N8N_PRIVATE_EXTENSION_RELEASE_RE = re.compile(r"^[0-9]+\.[0-9]+\.[0-9]+-[a-f0-9]{16}$")
N8N_PRIVATE_EXTENSION_NODES = (
    "dist/nodes/NdcDataProductPublish/NdcDataProductPublish.node.js",
    "dist/nodes/NdcDataProductRead/NdcDataProductRead.node.js",
    "dist/nodes/NdcFoundryBinding/NdcFoundryBinding.node.js",
)
N8N_PRIVATE_EXTENSION_CREDENTIALS = (
    "dist/credentials/NdcDataProductWriterApi.credentials.js",
    "dist/credentials/NdcDataProductReaderApi.credentials.js",
    "dist/credentials/NdcFoundryBindingApi.credentials.js",
    "dist/credentials/NdcProviderRotatingAccessApi.credentials.js",
)
ENGINE_N8N_NODE_TYPES = (
    "n8n-nodes-ndc.ndcDataProductPublish",
    "n8n-nodes-ndc.ndcDataProductRead",
    "n8n-nodes-ndc.ndcFoundryBinding",
)
ENGINE_N8N_CREDENTIAL_TYPES = (
    "ndcDataProductWriterApi",
    "ndcDataProductReaderApi",
    "ndcFoundryBindingApi",
    "ndcProviderRotatingAccessApi",
)
ENGINE_N8N_CREDENTIAL_TYPES_BY_RELEASE = {
    "0.1.2-05e4b38b14b4a019": ENGINE_N8N_CREDENTIAL_TYPES[:3],
    "0.1.3-3354149b5245e39a": ENGINE_N8N_CREDENTIAL_TYPES[:3],
    "0.1.4-59dc9f7882721d6a": ENGINE_N8N_CREDENTIAL_TYPES,
    "0.1.5-3c8ae53f010d7c88": ENGINE_N8N_CREDENTIAL_TYPES,
    "0.1.6-25cc2d7a52a0d0ee": ENGINE_N8N_CREDENTIAL_TYPES,
}
ENGINE_CREDENTIAL_SINK_ARTIFACT_ENTRIES = (
    "nodedc-source/server/credentialPolicies/ndcPrivateNode.js",
    "nodedc-source/server/credentialSink",
    "nodedc-source/server/index.js",
    "nodedc-source/server/routes/engineAgentGateway.js",
    "nodedc-source/server/routes/engineCredentialSink.js",
    "nodedc-source/server/routes/n8n.js",
    "nodedc-source/server/routes/ndcAgentMcp.js",
    ENGINE_CREDENTIAL_BACKEND_OVERRIDE_TEMPLATE_REL,
)
ENGINE_DATA_PRODUCT_PUBLISH_GRANT_ARTIFACT_ENTRIES = (
    "nodedc-source/server/assets/provider-packages/v1/catalog.json",
    "nodedc-source/server/dataProductPublishGrant",
    "nodedc-source/server/engineAgents/store.js",
    "nodedc-source/server/routes/engineAgentGateway.js",
    "nodedc-source/server/routes/n8n.js",
    ENGINE_DATA_PRODUCT_PUBLISH_GRANT_OVERRIDE_REL,
)
ENGINE_DATA_PRODUCT_PUBLISH_GRANT_SOURCE_PREFIX = (
    "nodedc-source/server/dataProductPublishGrant/"
)
ENGINE_DATA_PRODUCT_PUBLISH_GRANT_SOURCE_FILES = (
    "acceptance.js",
    "providerCatalog.js",
    "service.js",
    "signedDataPlaneClient.js",
    "store.js",
)
ENGINE_PUBLISH_GRANT_COMPOSITE_PROVIDER_CATALOG_PREDECESSOR_SHA256 = (
    "992159fc457ec76ce1f45aad337604c8a72b29252d44fbccda515f0fd6ea6428"
)
ENGINE_PUBLISH_GRANT_COMPOSITE_PROVIDER_CATALOG_TARGET_SHA256 = (
    "9c931f9abfcadb5b34a8a854c2efb8fd79913e000eecf0967d1b7c500bf9a56a"
)
ENGINE_PUBLISH_GRANT_COMPOSITE_PROVIDER_CHANGED_PATHS = (
    "nodedc-source/server/assets/provider-packages/v1/catalog.json",
    "nodedc-source/server/dataProductPublishGrant/providerCatalog.js",
    "nodedc-source/server/dataProductPublishGrant/service.js",
    "nodedc-source/server/dataProductPublishGrant/store.js",
)
ENGINE_COMPOSITE_PROVIDER_V4_ARTIFACT_ENTRIES = (
    "nodedc-source/server/assets/provider-packages/v1/catalog.json",
    "nodedc-source/server/dataProductPublishGrant/providerCatalog.js",
    "nodedc-source/server/dataProductPublishGrant/service.js",
    "nodedc-source/server/dataProductPublishGrant/store.js",
)
ENGINE_COMPOSITE_PROVIDER_V4_PREDECESSOR_SHA256 = {
    "nodedc-source/server/assets/provider-packages/v1/catalog.json": "992159fc457ec76ce1f45aad337604c8a72b29252d44fbccda515f0fd6ea6428",
    "nodedc-source/server/dataProductPublishGrant/providerCatalog.js": "901b8fad80018ce177b34ced804b39cb140a47e831414057f484296b373c651d",
    # Publish Grant 20260718-004 was applied after MCP Control Plane
    # 20260718-003 and is therefore the authoritative installed predecessor.
    "nodedc-source/server/dataProductPublishGrant/service.js": "6a417b25b080c05b40c771df4e2dca163491af2c9083ff73dc7e54ad3b360241",
    "nodedc-source/server/dataProductPublishGrant/store.js": "a92303b2732e21f68c1ac732fa26e4983cbadf3515741cee983b916a283d754c",
}
ENGINE_COMPOSITE_PROVIDER_V4_TARGET_SHA256 = {
    "nodedc-source/server/assets/provider-packages/v1/catalog.json": "9c931f9abfcadb5b34a8a854c2efb8fd79913e000eecf0967d1b7c500bf9a56a",
    "nodedc-source/server/dataProductPublishGrant/providerCatalog.js": "689c6fbf695e582d983159973a21142787d1b19bb1d343da4c62c03092ac291f",
    "nodedc-source/server/dataProductPublishGrant/service.js": "83f045f4e0f332644310172ed51bb652d808bf04155b11c02e46bdffc95f7220",
    "nodedc-source/server/dataProductPublishGrant/store.js": "98662da6acd0489a9cae4b726eb61ce89d9b2c788b2ea95433e9c4f02930c095",
}
ENGINE_PROVIDER_ROTATING_SLOT_ARTIFACT_ENTRIES = (
    "nodedc-source/server/assets/provider-packages/v1/catalog.json",
    "nodedc-source/server/dataProductPublishGrant/providerCatalog.js",
)
ENGINE_PROVIDER_ROTATING_SLOT_PREDECESSOR_SHA256 = {
    "nodedc-source/server/assets/provider-packages/v1/catalog.json": "9c931f9abfcadb5b34a8a854c2efb8fd79913e000eecf0967d1b7c500bf9a56a",
    "nodedc-source/server/dataProductPublishGrant/providerCatalog.js": "689c6fbf695e582d983159973a21142787d1b19bb1d343da4c62c03092ac291f",
}
ENGINE_PROVIDER_ROTATING_SLOT_TARGET_SHA256 = {
    "nodedc-source/server/assets/provider-packages/v1/catalog.json": "17f3e368f3264cbbd708965c9e1fd735aa974f15a1383bf88cd6d14a43dbf32d",
    "nodedc-source/server/dataProductPublishGrant/providerCatalog.js": "f6cf5f4de9e57f87fb904e2136a9f34d494e1ffc289aec3ed9ed788b5583a062",
}
ENGINE_PROVIDER_AUTHORITY_DIAGNOSTICS_ARTIFACT_ENTRIES = (
    "nodedc-source/server/nodeIntelligence/upstreamProjection.js",
    ENGINE_NODE_INTELLIGENCE_DESCRIPTOR_REL,
)
ENGINE_PROVIDER_AUTHORITY_DIAGNOSTICS_PREDECESSOR_SHA256 = {
    "nodedc-source/server/nodeIntelligence/upstreamProjection.js": "761a874b102a938bc6018159ddacdaac71ad6ae08e9f0f8d7f3b58a0165a5131",
    ENGINE_NODE_INTELLIGENCE_DESCRIPTOR_REL: "8d65991fbc23578fd3e4830844d52827212c78aa94a9cb3d13bac7594b888497",
}
ENGINE_PROVIDER_AUTHORITY_DIAGNOSTICS_TARGET_SHA256 = {
    "nodedc-source/server/nodeIntelligence/upstreamProjection.js": "2dfa6b4f37d9bfa8b92a8109d4060d02dd2634ceb8f7924504b83ccf3fdd1523",
    ENGINE_NODE_INTELLIGENCE_DESCRIPTOR_REL: "84b0e15a10cedf334ad04d6f31c908da2dc155503c9974f0eeb75b01e20fb884",
}
ENGINE_DEPTTRANS_ZONE_AUTHORITY_V1_ARTIFACT_ENTRIES = (
    "nodedc-source/server/assets/provider-packages/v1/catalog.json",
    "nodedc-source/server/assets/provider-packages/v1/depttrans-zone-authority-v1.json",
    "nodedc-source/server/dataProductPublishGrant/providerCatalog.js",
    "nodedc-source/server/dataProductPublishGrant/service.js",
    "nodedc-source/server/dataProductPublishGrant/store.js",
)
ENGINE_DEPTTRANS_ZONE_AUTHORITY_V1_PREDECESSOR_SHA256 = {
    "nodedc-source/server/assets/provider-packages/v1/catalog.json": "63e0741646197f0b1b3c64a4095e1bc8fb3a95ee6caf20b0293f89d869c9e620",
    "nodedc-source/server/dataProductPublishGrant/providerCatalog.js": "1a14299167ebe17efd677fa3c59b84c80e12d6846bac6f40f9bcae0729ab22c6",
    "nodedc-source/server/dataProductPublishGrant/service.js": "83f045f4e0f332644310172ed51bb652d808bf04155b11c02e46bdffc95f7220",
    "nodedc-source/server/dataProductPublishGrant/store.js": "98662da6acd0489a9cae4b726eb61ce89d9b2c788b2ea95433e9c4f02930c095",
}
ENGINE_DEPTTRANS_ZONE_AUTHORITY_V1_TARGET_SHA256 = {
    "nodedc-source/server/assets/provider-packages/v1/catalog.json": "1aac712a05e55137d69eedaf363969460ffe866288e8e18e35711967ab232f39",
    "nodedc-source/server/assets/provider-packages/v1/depttrans-zone-authority-v1.json": "1482032178b4816e599df570face9b1dfa8ae1fa2943ac8f941c561e8cb9aa9d",
    "nodedc-source/server/dataProductPublishGrant/providerCatalog.js": "e4c216b0affd89ddbd48abcec86febd48eb12a4c56507851daeb47f2ccd60c9a",
    "nodedc-source/server/dataProductPublishGrant/service.js": "408836564e9a422eb5e648cc24d764f4bfdf7f83d93306742e8615fa8186a642",
    "nodedc-source/server/dataProductPublishGrant/store.js": "ace5971d0772e9a9499f0849e6b754e3677cc2ca3080e573a12e26acf5a6c0c0",
}
ENGINE_DEPTTRANS_ZONE_AUTHORITY_V1_NEW_PATHS = (
    "nodedc-source/server/assets/provider-packages/v1/depttrans-zone-authority-v1.json",
)
ENGINE_PROVIDER_TARGET_HOST_POLICY_ARTIFACT_ENTRIES = (
    "nodedc-source/server/routes/n8n.js",
)
ENGINE_PROVIDER_TARGET_HOST_POLICY_PREDECESSOR_SHA256 = {
    "nodedc-source/server/routes/n8n.js": "f293a7794405badbabd2bf7ef088f96fe1167d9e249f05cbfc8af280a0d3e8f8",
}
ENGINE_PROVIDER_TARGET_HOST_POLICY_TARGET_SHA256 = {
    "nodedc-source/server/routes/n8n.js": "9bc3638e271102abec91bb80413329befb89d60c0e4dc0548f0dd11e93220d0a",
}
ENGINE_MCP_EXECUTION_PROFILE_DECODER_DESCRIPTOR_REL = (
    "nodedc-source/server/deployTransitions/executionProfileDecoderV1.json"
)
ENGINE_MCP_EXECUTION_PROFILE_DECODER_ARTIFACT_ENTRIES = (
    "nodedc-source/server/routes/n8n.js",
    ENGINE_MCP_EXECUTION_PROFILE_DECODER_DESCRIPTOR_REL,
)
ENGINE_MCP_EXECUTION_PROFILE_DECODER_PREDECESSOR_SHA256 = {
    "nodedc-source/server/routes/n8n.js": "752cb1524160adc1c95163c34e139b615c063d2ce8980f2a63879bddbd0f1e08",
}
ENGINE_MCP_EXECUTION_PROFILE_DECODER_TARGET_SHA256 = {
    "nodedc-source/server/routes/n8n.js": "1c2427c1d5830c40b1e8ae05f3d683fc39d07d7e0fe2431b0f6efbbb1d3fcb88",
    ENGINE_MCP_EXECUTION_PROFILE_DECODER_DESCRIPTOR_REL: "93e431902e9bcd3b828a82ed6b42b48d939051f21bf8824dafcf2addac8a711c",
}
ENGINE_MCP_EXECUTION_PROFILE_DECODER_NEW_PATHS = (
    ENGINE_MCP_EXECUTION_PROFILE_DECODER_DESCRIPTOR_REL,
)
ENGINE_MCP_TELEMETRY_CATALOG_DESCRIPTOR_REL = (
    "nodedc-source/server/deployTransitions/telemetryReadingCatalogV1.json"
)
ENGINE_MCP_TELEMETRY_CATALOG_ARTIFACT_ENTRIES = (
    "nodedc-source/server/routes/n8n.js",
    "nodedc-source/server/routes/engineAgentGateway.js",
    ENGINE_MCP_TELEMETRY_CATALOG_DESCRIPTOR_REL,
    ENGINE_NODE_INTELLIGENCE_DESCRIPTOR_REL,
)
ENGINE_MCP_TELEMETRY_CATALOG_PREDECESSOR_SHA256 = {
    "nodedc-source/server/routes/n8n.js": "1c2427c1d5830c40b1e8ae05f3d683fc39d07d7e0fe2431b0f6efbbb1d3fcb88",
    "nodedc-source/server/routes/engineAgentGateway.js": "4f600a2781be9118bec891fa2a6f20d7f55e0892ef2f06af24059193cebd28f4",
    ENGINE_NODE_INTELLIGENCE_DESCRIPTOR_REL: "63e7619c6971d02102583bb5d80d33ece293b952f113200fa0b76f0e88c2dd32",
}
ENGINE_MCP_TELEMETRY_CATALOG_FOUNDATION_SHA256 = {
    ENGINE_MCP_EXECUTION_PROFILE_DECODER_DESCRIPTOR_REL: "93e431902e9bcd3b828a82ed6b42b48d939051f21bf8824dafcf2addac8a711c",
}
ENGINE_MCP_TELEMETRY_CATALOG_TARGET_SHA256 = {
    "nodedc-source/server/routes/n8n.js": "903245ae363e9b9ac161498f17988a38876a0e0ac8d80f3fa1b0112ceb7fe906",
    "nodedc-source/server/routes/engineAgentGateway.js": "69bfc91e913a3fad04e13aca86efb9d62f73c0c7d1f8f7200907494b29fa9e8d",
    ENGINE_MCP_TELEMETRY_CATALOG_DESCRIPTOR_REL: "b25ab8b6e6ad8ac24614c4630cc3635abe453464466d5a72238b05e48a24d882",
    ENGINE_NODE_INTELLIGENCE_DESCRIPTOR_REL: "25ed3efd858aaf82c242dba501f0acc0c6c3dc91e8845707a4d3325750eab59f",
}
ENGINE_MCP_TELEMETRY_CATALOG_NEW_PATHS = (
    ENGINE_MCP_TELEMETRY_CATALOG_DESCRIPTOR_REL,
)
ENGINE_MCP_EXECUTION_PLAN_MATERIALIZATION_DESCRIPTOR_REL = (
    "nodedc-source/server/deployTransitions/executionPlanMaterializationV1.json"
)
ENGINE_MCP_EXECUTION_PLAN_MATERIALIZATION_ARTIFACT_ENTRIES = (
    "nodedc-source/server/routes/n8n.js",
    "nodedc-source/server/routes/engineAgentGateway.js",
    "nodedc-source/server/l2ExecutionPlan/catalog.js",
    "nodedc-source/server/l2ExecutionPlan/compiler.js",
    "nodedc-source/server/l2ExecutionPlan/materializer.js",
    "nodedc-source/server/assets/execution-plans/v1/catalog.json",
    ENGINE_MCP_EXECUTION_PLAN_MATERIALIZATION_DESCRIPTOR_REL,
    ENGINE_NODE_INTELLIGENCE_DESCRIPTOR_REL,
)
ENGINE_MCP_EXECUTION_PLAN_MATERIALIZATION_PREDECESSOR_SHA256 = {
    "nodedc-source/server/routes/n8n.js": "903245ae363e9b9ac161498f17988a38876a0e0ac8d80f3fa1b0112ceb7fe906",
    "nodedc-source/server/routes/engineAgentGateway.js": "69bfc91e913a3fad04e13aca86efb9d62f73c0c7d1f8f7200907494b29fa9e8d",
    ENGINE_NODE_INTELLIGENCE_DESCRIPTOR_REL: "25ed3efd858aaf82c242dba501f0acc0c6c3dc91e8845707a4d3325750eab59f",
}
ENGINE_MCP_EXECUTION_PLAN_MATERIALIZATION_FOUNDATION_SHA256 = {
    ENGINE_MCP_EXECUTION_PROFILE_DECODER_DESCRIPTOR_REL: "93e431902e9bcd3b828a82ed6b42b48d939051f21bf8824dafcf2addac8a711c",
    ENGINE_MCP_TELEMETRY_CATALOG_DESCRIPTOR_REL: "b25ab8b6e6ad8ac24614c4630cc3635abe453464466d5a72238b05e48a24d882",
}
ENGINE_MCP_EXECUTION_PLAN_MATERIALIZATION_TARGET_SHA256 = {
    "nodedc-source/server/routes/n8n.js": "391fc81228fdacd6efc6c0868991a3485f71869708e49ac15819db6ccce1bfce",
    "nodedc-source/server/routes/engineAgentGateway.js": "9020cf49a3558c0497fed4ecfd81367cbc11b5b249881804c29fe437900c71f8",
    "nodedc-source/server/l2ExecutionPlan/catalog.js": "c35b4c7ad9319aabbf1366a11ff52a6e99d961893bafdfcb4e84fc5f24fc04be",
    "nodedc-source/server/l2ExecutionPlan/compiler.js": "beb3f664073f9a372432643936a04d0cb0028cd695f759c68bd053e9cd892fe4",
    "nodedc-source/server/l2ExecutionPlan/materializer.js": "ee3bcfd06b3a5fa46800df974a2dedfdd55eeaf662329f837486c011a9bd713e",
    "nodedc-source/server/assets/execution-plans/v1/catalog.json": "a153e040e0a592bad4375b98d9a1d83d148923aa0f0fd47d225b92eda281c4e9",
    ENGINE_MCP_EXECUTION_PLAN_MATERIALIZATION_DESCRIPTOR_REL: "52c0152cff49c251be5581a9209d2e63ba710c16e815bdd6ece24f7c9dd7e480",
    ENGINE_NODE_INTELLIGENCE_DESCRIPTOR_REL: "03b2ba120c3929e9cf99940ddc927082de376ceff762895a84103144202aef42",
}
ENGINE_MCP_EXECUTION_PLAN_MATERIALIZATION_NEW_PATHS = (
    "nodedc-source/server/l2ExecutionPlan/catalog.js",
    "nodedc-source/server/l2ExecutionPlan/compiler.js",
    "nodedc-source/server/l2ExecutionPlan/materializer.js",
    "nodedc-source/server/assets/execution-plans/v1/catalog.json",
    ENGINE_MCP_EXECUTION_PLAN_MATERIALIZATION_DESCRIPTOR_REL,
)
ENGINE_MCP_EXECUTION_PLAN_TELEMETRY_RUNTIME_DESCRIPTOR_REL = (
    "nodedc-source/server/deployTransitions/executionPlanTelemetryRuntimeV2.json"
)
ENGINE_MCP_EXECUTION_PLAN_TELEMETRY_RUNTIME_ARTIFACT_ENTRIES = (
    "nodedc-source/server/l2ExecutionPlan/compiler.js",
    "nodedc-source/server/assets/execution-plans/v1/catalog.json",
    ENGINE_MCP_EXECUTION_PLAN_TELEMETRY_RUNTIME_DESCRIPTOR_REL,
)
ENGINE_MCP_EXECUTION_PLAN_TELEMETRY_RUNTIME_PREDECESSOR_SHA256 = {
    "nodedc-source/server/l2ExecutionPlan/compiler.js":
        "beb3f664073f9a372432643936a04d0cb0028cd695f759c68bd053e9cd892fe4",
    "nodedc-source/server/assets/execution-plans/v1/catalog.json":
        "a153e040e0a592bad4375b98d9a1d83d148923aa0f0fd47d225b92eda281c4e9",
}
ENGINE_MCP_EXECUTION_PLAN_TELEMETRY_RUNTIME_FOUNDATION_SHA256 = {
    "nodedc-source/server/routes/n8n.js":
        "391fc81228fdacd6efc6c0868991a3485f71869708e49ac15819db6ccce1bfce",
    "nodedc-source/server/routes/engineAgentGateway.js":
        "9020cf49a3558c0497fed4ecfd81367cbc11b5b249881804c29fe437900c71f8",
    "nodedc-source/server/l2ExecutionPlan/catalog.js":
        "c35b4c7ad9319aabbf1366a11ff52a6e99d961893bafdfcb4e84fc5f24fc04be",
    "nodedc-source/server/l2ExecutionPlan/materializer.js":
        "ee3bcfd06b3a5fa46800df974a2dedfdd55eeaf662329f837486c011a9bd713e",
    ENGINE_MCP_EXECUTION_PLAN_MATERIALIZATION_DESCRIPTOR_REL:
        "52c0152cff49c251be5581a9209d2e63ba710c16e815bdd6ece24f7c9dd7e480",
    ENGINE_NODE_INTELLIGENCE_DESCRIPTOR_REL:
        "03b2ba120c3929e9cf99940ddc927082de376ceff762895a84103144202aef42",
}
ENGINE_MCP_EXECUTION_PLAN_TELEMETRY_RUNTIME_TARGET_SHA256 = {
    "nodedc-source/server/l2ExecutionPlan/compiler.js":
        "6b783ad15c26dc7de0645082c8a426002d943138c70bf31a240247b16a33b6a0",
    "nodedc-source/server/assets/execution-plans/v1/catalog.json":
        "5bdfc92284a7c836ff326e3a89b559110e376b32efd34b5f23f2bec272745781",
    ENGINE_MCP_EXECUTION_PLAN_TELEMETRY_RUNTIME_DESCRIPTOR_REL:
        "68b275efb6303284336d8b637c966c24d891a4bd0b3fec4fb83247359929ef79",
}
ENGINE_MCP_EXECUTION_PLAN_TELEMETRY_RUNTIME_NEW_PATHS = (
    ENGINE_MCP_EXECUTION_PLAN_TELEMETRY_RUNTIME_DESCRIPTOR_REL,
)
ENGINE_MCP_EXECUTION_PLAN_MODULE_OWNERSHIP_DESCRIPTOR_REL = (
    "nodedc-source/server/deployTransitions/executionPlanModuleOwnershipV3.json"
)
ENGINE_MCP_EXECUTION_PLAN_MODULE_OWNERSHIP_ARTIFACT_ENTRIES = (
    "nodedc-source/server/l2ExecutionPlan/materializer.js",
    "nodedc-source/server/routes/engineAgentGateway.js",
    "nodedc-source/server/assets/execution-plans/v1/catalog.json",
    ENGINE_MCP_EXECUTION_PLAN_MODULE_OWNERSHIP_DESCRIPTOR_REL,
    ENGINE_NODE_INTELLIGENCE_DESCRIPTOR_REL,
)
ENGINE_MCP_EXECUTION_PLAN_MODULE_OWNERSHIP_PREDECESSOR_SHA256 = {
    "nodedc-source/server/l2ExecutionPlan/materializer.js":
        "ee3bcfd06b3a5fa46800df974a2dedfdd55eeaf662329f837486c011a9bd713e",
    "nodedc-source/server/routes/engineAgentGateway.js":
        "9020cf49a3558c0497fed4ecfd81367cbc11b5b249881804c29fe437900c71f8",
    "nodedc-source/server/assets/execution-plans/v1/catalog.json":
        "5bdfc92284a7c836ff326e3a89b559110e376b32efd34b5f23f2bec272745781",
    ENGINE_NODE_INTELLIGENCE_DESCRIPTOR_REL:
        "03b2ba120c3929e9cf99940ddc927082de376ceff762895a84103144202aef42",
}
ENGINE_MCP_EXECUTION_PLAN_MODULE_OWNERSHIP_FOUNDATION_SHA256 = {
    "nodedc-source/server/routes/n8n.js":
        "391fc81228fdacd6efc6c0868991a3485f71869708e49ac15819db6ccce1bfce",
    "nodedc-source/server/l2ExecutionPlan/catalog.js":
        "c35b4c7ad9319aabbf1366a11ff52a6e99d961893bafdfcb4e84fc5f24fc04be",
    "nodedc-source/server/l2ExecutionPlan/compiler.js":
        "6b783ad15c26dc7de0645082c8a426002d943138c70bf31a240247b16a33b6a0",
    ENGINE_MCP_EXECUTION_PLAN_MATERIALIZATION_DESCRIPTOR_REL:
        "52c0152cff49c251be5581a9209d2e63ba710c16e815bdd6ece24f7c9dd7e480",
    ENGINE_MCP_EXECUTION_PLAN_TELEMETRY_RUNTIME_DESCRIPTOR_REL:
        "68b275efb6303284336d8b637c966c24d891a4bd0b3fec4fb83247359929ef79",
}
ENGINE_MCP_EXECUTION_PLAN_MODULE_OWNERSHIP_TARGET_SHA256 = {
    "nodedc-source/server/l2ExecutionPlan/materializer.js":
        "dabf0073520049d7a04d1962b29e591ae092b87b287a50534ad2d98b03ae683c",
    "nodedc-source/server/routes/engineAgentGateway.js":
        "17c5f502b3ceacc45278eef7418d08e1e55a8b3e46e00942e559d25566fdba41",
    "nodedc-source/server/assets/execution-plans/v1/catalog.json":
        "7e34b93aa30b06cd52853b48013baef2970cc27e4fddc333a1011dc73ea8c08a",
    ENGINE_MCP_EXECUTION_PLAN_MODULE_OWNERSHIP_DESCRIPTOR_REL:
        "d187d539a219fec453e06c55c3f5486ef66059371b4ae9b145266307b2af9889",
    ENGINE_NODE_INTELLIGENCE_DESCRIPTOR_REL:
        "4cdeb85ebb2e43f088f095f75b7fc31aabd8ab81c8ac96ded4aafd7dbd8e30bd",
}
ENGINE_MCP_EXECUTION_PLAN_MODULE_OWNERSHIP_NEW_PATHS = (
    ENGINE_MCP_EXECUTION_PLAN_MODULE_OWNERSHIP_DESCRIPTOR_REL,
)
ENGINE_MCP_NORMALIZED_IDENTITY_SEARCH_DESCRIPTOR_REL = (
    "nodedc-source/server/deployTransitions/normalizedIdentitySearchV1.json"
)
ENGINE_MCP_NORMALIZED_IDENTITY_SEARCH_ARTIFACT_ENTRIES = (
    "nodedc-source/server/routes/n8n.js",
    "nodedc-source/server/routes/engineAgentGateway.js",
    "nodedc-source/server/l2ExecutionPlan/compiler.js",
    "nodedc-source/server/assets/execution-plans/v1/catalog.json",
    "nodedc-source/server/assets/provider-packages/v1/catalog.json",
    ENGINE_MCP_NORMALIZED_IDENTITY_SEARCH_DESCRIPTOR_REL,
    ENGINE_NODE_INTELLIGENCE_DESCRIPTOR_REL,
)
ENGINE_MCP_NORMALIZED_IDENTITY_SEARCH_PREDECESSOR_SHA256 = {
    "nodedc-source/server/routes/n8n.js":
        "391fc81228fdacd6efc6c0868991a3485f71869708e49ac15819db6ccce1bfce",
    "nodedc-source/server/routes/engineAgentGateway.js":
        "17c5f502b3ceacc45278eef7418d08e1e55a8b3e46e00942e559d25566fdba41",
    "nodedc-source/server/l2ExecutionPlan/compiler.js":
        "4854a62fb44cb3dd715f2cb8728740575453a666f5c31abe9d41bc2562be5e95",
    "nodedc-source/server/assets/execution-plans/v1/catalog.json":
        "2e70b607b4a347592ce2f4732f6da0781ac94ec4829ac336021cb501fdafe9aa",
    "nodedc-source/server/assets/provider-packages/v1/catalog.json":
        "2fce1c623a8acf9c01a43463e6d38eda71ad28379a2d91b2ca40f31f8dccf3c6",
    ENGINE_NODE_INTELLIGENCE_DESCRIPTOR_REL:
        "4cdeb85ebb2e43f088f095f75b7fc31aabd8ab81c8ac96ded4aafd7dbd8e30bd",
}
ENGINE_MCP_NORMALIZED_IDENTITY_SEARCH_FOUNDATION_SHA256 = {
    "nodedc-source/server/l2ExecutionPlan/catalog.js":
        "c35b4c7ad9319aabbf1366a11ff52a6e99d961893bafdfcb4e84fc5f24fc04be",
    "nodedc-source/server/l2ExecutionPlan/materializer.js":
        "dabf0073520049d7a04d1962b29e591ae092b87b287a50534ad2d98b03ae683c",
    ENGINE_MCP_EXECUTION_PROFILE_DECODER_DESCRIPTOR_REL:
        "93e431902e9bcd3b828a82ed6b42b48d939051f21bf8824dafcf2addac8a711c",
    ENGINE_MCP_TELEMETRY_CATALOG_DESCRIPTOR_REL:
        "b25ab8b6e6ad8ac24614c4630cc3635abe453464466d5a72238b05e48a24d882",
    ENGINE_MCP_EXECUTION_PLAN_MATERIALIZATION_DESCRIPTOR_REL:
        "52c0152cff49c251be5581a9209d2e63ba710c16e815bdd6ece24f7c9dd7e480",
    ENGINE_MCP_EXECUTION_PLAN_TELEMETRY_RUNTIME_DESCRIPTOR_REL:
        "68b275efb6303284336d8b637c966c24d891a4bd0b3fec4fb83247359929ef79",
    ENGINE_MCP_EXECUTION_PLAN_MODULE_OWNERSHIP_DESCRIPTOR_REL:
        "d187d539a219fec453e06c55c3f5486ef66059371b4ae9b145266307b2af9889",
}
ENGINE_MCP_NORMALIZED_IDENTITY_SEARCH_TARGET_SHA256 = {
    "nodedc-source/server/routes/n8n.js":
        "a2bc69c72f68e57ed27120d0c88f4ffe6310bbf0c4360c8b0dba0953ccaaf522",
    "nodedc-source/server/routes/engineAgentGateway.js":
        "4a9524fd954320277042c783b7b19cbb2172f075f27652c0eebfd743ffc47872",
    "nodedc-source/server/l2ExecutionPlan/compiler.js":
        "01958d541c778002d33e3aead0cfe02df2084eb7222ce941cc7149d73a10f135",
    "nodedc-source/server/assets/execution-plans/v1/catalog.json":
        "2b8e5ee3d73d16f3cd6e34d1f7394946a6270a17b0e9e6511f12921ba2561fd3",
    "nodedc-source/server/assets/provider-packages/v1/catalog.json":
        "fe5256fd2ba295819daecc8d2acae34687e807978a6730dfa20703cb3bab0c1b",
    ENGINE_MCP_NORMALIZED_IDENTITY_SEARCH_DESCRIPTOR_REL:
        "41738185fe103642912b0aa1c29c51860970c38f9f916cc3725e79e258b9ea7e",
    ENGINE_NODE_INTELLIGENCE_DESCRIPTOR_REL:
        "3e7aeb1d28eb291461f79cd656ece6488bc6d372124088e92f53bf89c3373f61",
}
ENGINE_MCP_NORMALIZED_IDENTITY_SEARCH_NEW_PATHS = (
    ENGINE_MCP_NORMALIZED_IDENTITY_SEARCH_DESCRIPTOR_REL,
)
ENGINE_MCP_L1_CREDENTIAL_REUSE_DESCRIPTOR_REL = (
    "nodedc-source/server/deployTransitions/l1CredentialReuseV1.json"
)
ENGINE_MCP_L1_CREDENTIAL_REUSE_ARTIFACT_ENTRIES = (
    "nodedc-source/server/routes/n8n.js",
    ENGINE_MCP_L1_CREDENTIAL_REUSE_DESCRIPTOR_REL,
)
ENGINE_MCP_L1_CREDENTIAL_REUSE_PREDECESSOR_SHA256 = {
    "nodedc-source/server/routes/n8n.js":
        "a2bc69c72f68e57ed27120d0c88f4ffe6310bbf0c4360c8b0dba0953ccaaf522",
}
ENGINE_MCP_L1_CREDENTIAL_REUSE_FOUNDATION_SHA256 = {
    "nodedc-source/server/routes/engineAgentGateway.js":
        "4a9524fd954320277042c783b7b19cbb2172f075f27652c0eebfd743ffc47872",
    ENGINE_MCP_NORMALIZED_IDENTITY_SEARCH_DESCRIPTOR_REL:
        "41738185fe103642912b0aa1c29c51860970c38f9f916cc3725e79e258b9ea7e",
    ENGINE_NODE_INTELLIGENCE_DESCRIPTOR_REL:
        "3e7aeb1d28eb291461f79cd656ece6488bc6d372124088e92f53bf89c3373f61",
}
ENGINE_MCP_L1_CREDENTIAL_REUSE_TARGET_SHA256 = {
    "nodedc-source/server/routes/n8n.js":
        "6620e4bdd573e9f6b636a4b059eafef76d59da2fdb2183038fa5ec95357d8478",
    ENGINE_MCP_L1_CREDENTIAL_REUSE_DESCRIPTOR_REL:
        "2ada49ef8bb2f146a9ea8d3c9ab5ee55f6a4e1b17e0f4b62a16f27368bd0eb05",
}
ENGINE_MCP_L1_CREDENTIAL_REUSE_NEW_PATHS = (
    ENGINE_MCP_L1_CREDENTIAL_REUSE_DESCRIPTOR_REL,
)
ENGINE_MCP_L1_CREDENTIAL_PROVENANCE_DESCRIPTOR_REL = (
    "nodedc-source/server/deployTransitions/l1CredentialProvenanceV2.json"
)
ENGINE_MCP_L1_CREDENTIAL_PROVENANCE_ARTIFACT_ENTRIES = (
    "nodedc-source/server/routes/n8n.js",
    ENGINE_MCP_L1_CREDENTIAL_PROVENANCE_DESCRIPTOR_REL,
)
ENGINE_MCP_L1_CREDENTIAL_PROVENANCE_PREDECESSOR_SHA256 = {
    "nodedc-source/server/routes/n8n.js":
        "6620e4bdd573e9f6b636a4b059eafef76d59da2fdb2183038fa5ec95357d8478",
}
ENGINE_MCP_L1_CREDENTIAL_PROVENANCE_FOUNDATION_SHA256 = {
    "nodedc-source/server/routes/engineAgentGateway.js":
        "4a9524fd954320277042c783b7b19cbb2172f075f27652c0eebfd743ffc47872",
    ENGINE_MCP_NORMALIZED_IDENTITY_SEARCH_DESCRIPTOR_REL:
        "41738185fe103642912b0aa1c29c51860970c38f9f916cc3725e79e258b9ea7e",
    ENGINE_NODE_INTELLIGENCE_DESCRIPTOR_REL:
        "3e7aeb1d28eb291461f79cd656ece6488bc6d372124088e92f53bf89c3373f61",
    ENGINE_MCP_L1_CREDENTIAL_REUSE_DESCRIPTOR_REL:
        "2ada49ef8bb2f146a9ea8d3c9ab5ee55f6a4e1b17e0f4b62a16f27368bd0eb05",
}
ENGINE_MCP_L1_CREDENTIAL_PROVENANCE_TARGET_SHA256 = {
    "nodedc-source/server/routes/n8n.js":
        "af07edcf784c420855134ab9178f020d259a1cac703cd643418ab7b4eb94dbd3",
    ENGINE_MCP_L1_CREDENTIAL_PROVENANCE_DESCRIPTOR_REL:
        "5887da6e5cb611450e03a110be9786acbe47ae1b00217b8bf09e0967f71f6a3d",
}
ENGINE_MCP_L1_CREDENTIAL_PROVENANCE_NEW_PATHS = (
    ENGINE_MCP_L1_CREDENTIAL_PROVENANCE_DESCRIPTOR_REL,
)
ENGINE_MCP_EXECUTION_PLAN_SANDBOX_RUNTIME_DESCRIPTOR_REL = (
    "nodedc-source/server/deployTransitions/executionPlanSandboxRuntimeV4.json"
)
ENGINE_MCP_EXECUTION_PLAN_SANDBOX_RUNTIME_ARTIFACT_ENTRIES = (
    "nodedc-source/server/l2ExecutionPlan/compiler.js",
    ENGINE_MCP_EXECUTION_PLAN_SANDBOX_RUNTIME_DESCRIPTOR_REL,
)
ENGINE_MCP_EXECUTION_PLAN_SANDBOX_RUNTIME_PREDECESSOR_SHA256 = {
    "nodedc-source/server/l2ExecutionPlan/compiler.js":
        "01958d541c778002d33e3aead0cfe02df2084eb7222ce941cc7149d73a10f135",
}
ENGINE_MCP_EXECUTION_PLAN_SANDBOX_RUNTIME_FOUNDATION_SHA256 = {
    "nodedc-source/server/l2ExecutionPlan/materializer.js":
        "dabf0073520049d7a04d1962b29e591ae092b87b287a50534ad2d98b03ae683c",
    "nodedc-source/server/routes/engineAgentGateway.js":
        "4a9524fd954320277042c783b7b19cbb2172f075f27652c0eebfd743ffc47872",
    "nodedc-source/server/assets/execution-plans/v1/catalog.json":
        "2b8e5ee3d73d16f3cd6e34d1f7394946a6270a17b0e9e6511f12921ba2561fd3",
    "nodedc-source/server/assets/provider-packages/v1/catalog.json":
        "fe5256fd2ba295819daecc8d2acae34687e807978a6730dfa20703cb3bab0c1b",
    ENGINE_MCP_NORMALIZED_IDENTITY_SEARCH_DESCRIPTOR_REL:
        "41738185fe103642912b0aa1c29c51860970c38f9f916cc3725e79e258b9ea7e",
    ENGINE_MCP_L1_CREDENTIAL_PROVENANCE_DESCRIPTOR_REL:
        "5887da6e5cb611450e03a110be9786acbe47ae1b00217b8bf09e0967f71f6a3d",
}
ENGINE_MCP_EXECUTION_PLAN_SANDBOX_RUNTIME_TARGET_SHA256 = {
    "nodedc-source/server/l2ExecutionPlan/compiler.js":
        "64f5196a83018505c6dac77a0f8674c27941257a874eed9b024c1c94f169be2b",
    ENGINE_MCP_EXECUTION_PLAN_SANDBOX_RUNTIME_DESCRIPTOR_REL:
        "a4692643afb86dfeeee6ca24aefcc181913e715eff38fa158667d2f10b901847",
}
ENGINE_MCP_EXECUTION_PLAN_SANDBOX_RUNTIME_NEW_PATHS = (
    ENGINE_MCP_EXECUTION_PLAN_SANDBOX_RUNTIME_DESCRIPTOR_REL,
)
ENGINE_MCP_GELIOS_ITEMS_ENVELOPE_DESCRIPTOR_REL = (
    "nodedc-source/server/deployTransitions/geliosItemsEnvelopeV12.json"
)
ENGINE_MCP_GELIOS_ITEMS_ENVELOPE_ARTIFACT_ENTRIES = (
    "nodedc-source/server/assets/execution-plans/v1/catalog.json",
    "nodedc-source/server/assets/provider-packages/v1/catalog.json",
    ENGINE_MCP_GELIOS_ITEMS_ENVELOPE_DESCRIPTOR_REL,
)
ENGINE_MCP_GELIOS_ITEMS_ENVELOPE_PREDECESSOR_SHA256 = {
    "nodedc-source/server/assets/execution-plans/v1/catalog.json":
        "2b8e5ee3d73d16f3cd6e34d1f7394946a6270a17b0e9e6511f12921ba2561fd3",
    "nodedc-source/server/assets/provider-packages/v1/catalog.json":
        "fe5256fd2ba295819daecc8d2acae34687e807978a6730dfa20703cb3bab0c1b",
}
ENGINE_MCP_GELIOS_ITEMS_ENVELOPE_FOUNDATION_SHA256 = {
    "nodedc-source/server/l2ExecutionPlan/compiler.js":
        "64f5196a83018505c6dac77a0f8674c27941257a874eed9b024c1c94f169be2b",
    "nodedc-source/server/l2ExecutionPlan/materializer.js":
        "dabf0073520049d7a04d1962b29e591ae092b87b287a50534ad2d98b03ae683c",
    "nodedc-source/server/routes/engineAgentGateway.js":
        "4a9524fd954320277042c783b7b19cbb2172f075f27652c0eebfd743ffc47872",
    ENGINE_MCP_EXECUTION_PLAN_SANDBOX_RUNTIME_DESCRIPTOR_REL:
        "a4692643afb86dfeeee6ca24aefcc181913e715eff38fa158667d2f10b901847",
}
ENGINE_MCP_GELIOS_ITEMS_ENVELOPE_TARGET_SHA256 = {
    "nodedc-source/server/assets/execution-plans/v1/catalog.json":
        "eb0c32fa0e8017b23e2d225fcb2d5805aa6dd1bf674e8aa248afc6a4079a7403",
    "nodedc-source/server/assets/provider-packages/v1/catalog.json":
        "42104d1267ca7840446c0c02edd3f9ecb29f8da8eb3e8f384cbd6dca0f676c4c",
    ENGINE_MCP_GELIOS_ITEMS_ENVELOPE_DESCRIPTOR_REL:
        "16e39f54ebae776de9acfdf0078c79291310eeca5a1f720eb8b82496f4d419a3",
}
ENGINE_MCP_GELIOS_ITEMS_ENVELOPE_NEW_PATHS = (
    ENGINE_MCP_GELIOS_ITEMS_ENVELOPE_DESCRIPTOR_REL,
)
ENGINE_MCP_REGISTERED_EXECUTION_PROFILES_DESCRIPTOR_REL = (
    "nodedc-source/server/deployTransitions/registeredExecutionProfilesV2.json"
)
ENGINE_MCP_REGISTERED_EXECUTION_PROFILES_ARTIFACT_ENTRIES = (
    "nodedc-source/server/assets/execution-plans/v1/catalog.json",
    "nodedc-source/server/l2ExecutionPlan/catalog.js",
    "nodedc-source/server/l2ExecutionPlan/registeredProfiles.js",
    "nodedc-source/server/routes/engineAgentGateway.js",
    ENGINE_NODE_INTELLIGENCE_DESCRIPTOR_REL,
    ENGINE_MCP_REGISTERED_EXECUTION_PROFILES_DESCRIPTOR_REL,
)
ENGINE_MCP_REGISTERED_EXECUTION_PROFILES_PREDECESSOR_SHA256 = {
    "nodedc-source/server/assets/execution-plans/v1/catalog.json":
        "eb0c32fa0e8017b23e2d225fcb2d5805aa6dd1bf674e8aa248afc6a4079a7403",
    "nodedc-source/server/l2ExecutionPlan/catalog.js":
        "c35b4c7ad9319aabbf1366a11ff52a6e99d961893bafdfcb4e84fc5f24fc04be",
    "nodedc-source/server/routes/engineAgentGateway.js":
        "4a9524fd954320277042c783b7b19cbb2172f075f27652c0eebfd743ffc47872",
    ENGINE_NODE_INTELLIGENCE_DESCRIPTOR_REL:
        "3e7aeb1d28eb291461f79cd656ece6488bc6d372124088e92f53bf89c3373f61",
}
ENGINE_MCP_REGISTERED_EXECUTION_PROFILES_FOUNDATION_SHA256 = {
    "nodedc-source/server/l2ExecutionPlan/compiler.js":
        "64f5196a83018505c6dac77a0f8674c27941257a874eed9b024c1c94f169be2b",
    "nodedc-source/server/l2ExecutionPlan/materializer.js":
        "dabf0073520049d7a04d1962b29e591ae092b87b287a50534ad2d98b03ae683c",
    ENGINE_MCP_GELIOS_ITEMS_ENVELOPE_DESCRIPTOR_REL:
        "16e39f54ebae776de9acfdf0078c79291310eeca5a1f720eb8b82496f4d419a3",
}
ENGINE_MCP_REGISTERED_EXECUTION_PROFILES_TARGET_SHA256 = {
    "nodedc-source/server/assets/execution-plans/v1/catalog.json":
        "940510499a9260dbff718b7b1f96f72f8e9ac593b460805af3007731578a7668",
    "nodedc-source/server/l2ExecutionPlan/catalog.js":
        "fec56b154ae483ad21bbaaeb4c55707bffce223c27874ac135ce58a9203259a0",
    "nodedc-source/server/l2ExecutionPlan/registeredProfiles.js":
        "3c521c1652c61c9d757197c76e053fd3ec602e13ef7f6a4856835ecc1a8a61d1",
    "nodedc-source/server/routes/engineAgentGateway.js":
        "8f04edc11251de86b825351c92338be9537207887cf802474b6b6d8c3cce4077",
    ENGINE_NODE_INTELLIGENCE_DESCRIPTOR_REL:
        "3d72709e40b79c01a62a6af4bde911fca4f609d5ac487d284cf97fd8ebd73686",
    ENGINE_MCP_REGISTERED_EXECUTION_PROFILES_DESCRIPTOR_REL:
        "1db523f035a47c6b00b41b26efe1390ad2d24acece9d30dd039eff56626e934d",
}
ENGINE_MCP_REGISTERED_EXECUTION_PROFILES_NEW_PATHS = (
    "nodedc-source/server/l2ExecutionPlan/registeredProfiles.js",
    ENGINE_MCP_REGISTERED_EXECUTION_PROFILES_DESCRIPTOR_REL,
)
ENGINE_MCP_REGISTERED_EXECUTION_PROFILES_FAILED_PATHS = (
    "nodedc-source/server/deployTransitions/registeredExecutionProfilesV1.json",
)
ENGINE_MCP_GELIOS_UNITS_ITEMS_DESCRIPTOR_REL = (
    "nodedc-source/server/deployTransitions/"
    "geliosUnitsItemsEnvelopeV12Patch1.json"
)
ENGINE_MCP_GELIOS_UNITS_ITEMS_ARTIFACT_ENTRIES = (
    "nodedc-source/server/assets/execution-plans/v1/catalog.json",
    "nodedc-source/server/assets/provider-packages/v1/catalog.json",
    ENGINE_MCP_GELIOS_UNITS_ITEMS_DESCRIPTOR_REL,
)
ENGINE_MCP_GELIOS_UNITS_ITEMS_PREDECESSOR_SHA256 = {
    "nodedc-source/server/assets/execution-plans/v1/catalog.json":
        "940510499a9260dbff718b7b1f96f72f8e9ac593b460805af3007731578a7668",
    "nodedc-source/server/assets/provider-packages/v1/catalog.json":
        "42104d1267ca7840446c0c02edd3f9ecb29f8da8eb3e8f384cbd6dca0f676c4c",
}
ENGINE_MCP_GELIOS_UNITS_ITEMS_FOUNDATION_SHA256 = {
    "nodedc-source/server/l2ExecutionPlan/catalog.js":
        "fec56b154ae483ad21bbaaeb4c55707bffce223c27874ac135ce58a9203259a0",
    "nodedc-source/server/l2ExecutionPlan/compiler.js":
        "64f5196a83018505c6dac77a0f8674c27941257a874eed9b024c1c94f169be2b",
    "nodedc-source/server/l2ExecutionPlan/materializer.js":
        "dabf0073520049d7a04d1962b29e591ae092b87b287a50534ad2d98b03ae683c",
    "nodedc-source/server/l2ExecutionPlan/registeredProfiles.js":
        "3c521c1652c61c9d757197c76e053fd3ec602e13ef7f6a4856835ecc1a8a61d1",
    "nodedc-source/server/routes/engineAgentGateway.js":
        "8f04edc11251de86b825351c92338be9537207887cf802474b6b6d8c3cce4077",
    ENGINE_NODE_INTELLIGENCE_DESCRIPTOR_REL:
        "3d72709e40b79c01a62a6af4bde911fca4f609d5ac487d284cf97fd8ebd73686",
    ENGINE_MCP_REGISTERED_EXECUTION_PROFILES_DESCRIPTOR_REL:
        "1db523f035a47c6b00b41b26efe1390ad2d24acece9d30dd039eff56626e934d",
}
ENGINE_MCP_GELIOS_UNITS_ITEMS_TARGET_SHA256 = {
    "nodedc-source/server/assets/execution-plans/v1/catalog.json":
        "d0cc95fa5e55bda315947fdb13bd8a0d8931b9484677e4c4cc0dcb0e9614e215",
    "nodedc-source/server/assets/provider-packages/v1/catalog.json":
        "1f1b866b6f837bffc6d529dfffd8bfa9c87495bfcd9ae3515a79765143d94b1d",
    ENGINE_MCP_GELIOS_UNITS_ITEMS_DESCRIPTOR_REL:
        "7a1594573e98342d3a3edcc0dc4f663f06b30ca24cc20adb5f36d50591066d96",
}
ENGINE_MCP_GELIOS_UNITS_ITEMS_NEW_PATHS = (
    ENGINE_MCP_GELIOS_UNITS_ITEMS_DESCRIPTOR_REL,
)
ENGINE_AGENT_FULL_GRANT_MIGRATION_ARTIFACT_ENTRIES = (
    ENGINE_AGENT_FULL_GRANT_MIGRATION_STORE_REL,
)
ENGINE_DATA_PRODUCT_PUBLISH_GRANT_PREDECESSOR_SHA256 = {
    "docker-compose.yml": ENGINE_DATA_PRODUCT_PUBLISH_GRANT_PREDECESSOR_COMPOSE_SHA256,
    "nodedc-source/server/credentialPolicies/ndcPrivateNode.js": "723874a02dc7b8a68b22ff2304431cfe64f28933cedf5f1e6cda79b2e1cf704a",
    "nodedc-source/server/credentialSink/core.js": "9f0facc41fd398fcd955cffdd486abb126cdcd756c87ffde667fcbe00e2c41d3",
    "nodedc-source/server/credentialSink/requestAuth.js": "f8c9237c3e6f4219dee0d4f956d6e97f76f5bd7ba8a6fd0b4fb21aceffa38138",
    "nodedc-source/server/credentialSink/store.js": "c78dc285a973b6acd8a2330f0310935ad08720b2905454492f292d235abf12c0",
    "nodedc-source/server/credentialSink/vendor/engine-credential-sink.mjs": "b4800eead9bf94793ff1280d06e34aad6b37ef055a9d7f8d83d7fb5f9bd66d8b",
    "nodedc-source/server/index.js": "b2b790b02839570d967a2ca68b00e2724485a99389ac9b3a589a1b22302a36b8",
    "nodedc-source/server/routes/engineAgentGateway.js": "604a75ad3b9b463cea5e578760c8a23592e2e00b8acfc0099730a347e27bf4e8",
    "nodedc-source/server/routes/engineCredentialSink.js": "9cbb69dbc8cbe6181cd5b0170fe9c4d717b0a173866ca98cba3e3766c0bab94e",
    "nodedc-source/server/routes/n8n.js": "783d822e2457d82e890f43bc00c7e33822077dc2841f0511a89ecb210fd36d48",
    "nodedc-source/server/routes/ndcAgentMcp.js": "534e2c85e1faecc72a00da7ad32d0584ee09b6bd89eeec2221c3b23d80e1e962",
    ENGINE_CREDENTIAL_BACKEND_OVERRIDE_TEMPLATE_REL: "944fa64b08255eb8207b93fd327aebb98ecd9400d37d25fcfa8e3a040ee44afe",
}
ENGINE_DATA_PRODUCT_PUBLISH_GRANT_INSTALLED_FOUNDATION_SHA256 = {
    **ENGINE_DATA_PRODUCT_PUBLISH_GRANT_PREDECESSOR_SHA256,
    # This exact successor was installed by the later restart-safe-auth
    # transition; initial Publish-grant installation still uses the original
    # predecessor map above.
    "nodedc-source/server/index.js": "0ac408e0e9a7bc5c8e13a00afc957b982b065e2bc414919839e0b0a11aa05ba4",
}
ENGINE_CREDENTIAL_SINK_CONTRACT_SHA256 = "b4800eead9bf94793ff1280d06e34aad6b37ef055a9d7f8d83d7fb5f9bd66d8b"
ENGINE_BASE_COMPOSE_SERVICES = (
    "postgresql",
    "authentik-server",
    "authentik-worker",
    "n8n-postgres",
    "ops-postgres",
    "n8n",
    "nodedc-backend",
    "nodedc-frontend-build",
    "app",
)

COMPONENTS = {
    "engine": {
        "payload_root": Path("/volume2/nodedc-demo"),
        "compose_root": Path("/volume2/nodedc-demo"),
        "services": ("nodedc-backend", "app"),
        "compose_no_deps": True,
        "publish_dist": True,
        "healthchecks": (
            "http://127.0.0.1:8080/",
            "http://127.0.0.1:3001/health",
        ),
    },
    "launcher": {
        "payload_root": Path("/volume1/docker/nodedc-platform/launcher/source"),
        "build_root": Path("/volume1/docker/nodedc-platform/launcher/source"),
        "build": ("build", "--no-cache", "-t", "nodedc/launcher:local", "."),
        "compose_root": Path("/volume1/docker/nodedc-platform/platform"),
        "compose_env_file": Path("/volume1/docker/nodedc-platform/platform/.env.synology"),
        "compose_files": (
            Path("/volume1/docker/nodedc-platform/platform/docker-compose.platform-http.yml"),
        ),
        "compose_no_deps": True,
        "services": ("launcher",),
        "healthchecks": (
            {
                "url": "http://127.0.0.1:18080/healthz",
                "headers": {"Host": "hub.nodedc.ru"},
            },
        ),
    },
    "platform": {
        "payload_root": Path("/volume1/docker/nodedc-platform"),
        "compose_root": Path("/volume1/docker/nodedc-platform/platform"),
        "compose_env_file": Path("/volume1/docker/nodedc-platform/platform/.env.synology"),
        "compose_files": (
            Path("/volume1/docker/nodedc-platform/platform/docker-compose.platform-http.yml"),
            Path("/volume1/docker/nodedc-platform/platform/docker-compose.external-data-plane.yml"),
        ),
        "compose_no_deps": True,
        "services": ("notification-postgres", "notification-core", "ai-workspace-hub", "launcher", "reverse-proxy", "external-data-plane-postgres", "external-data-plane", "map-gateway"),
        "healthchecks": (
            "http://127.0.0.1:5185/healthz",
            "http://127.0.0.1:18081/healthz",
            {
                "url": "http://127.0.0.1:18080/healthz",
                "headers": {"Host": "hub.nodedc.ru"},
            },
            {
                "url": "http://127.0.0.1:18080/",
                "headers": {"Host": "id.nodedc.ru"},
            },
        ),
    },
    "tasker": {
        "payload_root": Path("/volume1/docker/nodedc-platform/tasker"),
        "compose_root": Path("/volume1/docker/nodedc-platform/tasker/plane-app"),
        "compose_project": "nodedc-tasker",
        "compose_env_file": Path("/volume1/docker/nodedc-platform/tasker/plane-app/.env.synology"),
        "compose_files": (
            Path("/volume1/docker/nodedc-platform/tasker/plane-app/docker-compose.yaml"),
            Path("/volume1/docker/nodedc-platform/tasker/plane-app/docker-compose.synology.override.yml"),
        ),
        "services": ("api", "worker", "beat-worker", "web"),
        "healthchecks": (
            {
                "url": "http://127.0.0.1:18090/",
                "headers": {"Host": "ops.nodedc.ru"},
            },
        ),
    },
    "ops-agents": {
        "payload_root": Path("/volume1/docker/nodedc-platform/ops-agents"),
        "compose_root": Path("/volume1/docker/nodedc-platform/ops-agents"),
        "compose_env_file": Path("/volume1/docker/nodedc-platform/ops-agents/.env"),
        "compose_files": (
            Path("/volume1/docker/nodedc-platform/ops-agents/docker-compose.synology.yml"),
        ),
        "compose_build": True,
        "compose_no_deps": True,
        "services": ("agent-gateway",),
        "healthchecks": (
            "http://172.22.0.222:18190/readyz",
        ),
    },
    "bim-viewer": {
        "payload_root": Path("/volume1/docker/nodedc-platform/bim-viewer/source"),
        "build_root": Path("/volume1/docker/nodedc-platform/bim-viewer/source/converter"),
        "build": ("build", "--no-cache", "-t", "nodedc/bim-converter:local", "."),
        "compose_root": Path("/volume1/docker/nodedc-platform/bim-viewer/source"),
        "compose_env_file": Path("/volume1/docker/nodedc-platform/bim-viewer/source/.env"),
        "compose_files": (
            Path("/volume1/docker/nodedc-platform/bim-viewer/source/docker-compose.beam.yml"),
        ),
        "compose_no_deps": True,
        "services": ("ndc-beam-viewer", "nodedc-bim-converter"),
        "healthchecks": (
            "http://127.0.0.1:18100/api/auth/session",
        ),
    },
    "n8n-private-extension": {
        # This component only stages a verified, immutable offline release in
        # Platform-owned storage. It deliberately has no Compose file, service,
        # container mutation or Engine activation side effect.
        "payload_root": N8N_PRIVATE_EXTENSION_RELEASES_ROOT,
        "bootstrap_root": True,
        "artifact_only": True,
        "immutable_payload": True,
        "services": (),
    },
    "module-foundry": {
        "payload_root": Path("/volume1/docker/nodedc-platform/module-foundry/source"),
        "compose_root": Path("/volume1/docker/nodedc-platform/module-foundry/source/infra"),
        "compose_project": "nodedc-module-foundry",
        "compose_env_file": Path("/volume1/docker/nodedc-platform/module-foundry/source/.env"),
        "compose_files": (
            Path("/volume1/docker/nodedc-platform/module-foundry/source/infra/docker-compose.module-foundry.yml"),
        ),
        "bootstrap_root": True,
        "compose_build": True,
        "compose_no_deps": True,
        "services": ("nodedc-module-foundry",),
        "healthchecks": (
            "http://172.22.0.222:9920/healthz",
        ),
    },
    "device-plane": {
        "payload_root": DEVICE_PLANE_ROOT,
        "compose_root": DEVICE_PLANE_ROOT,
        "compose_project": "nodedc-device-plane",
        "compose_files": (
            DEVICE_PLANE_ROOT / "docker-compose.device-plane.yml",
        ),
        "bootstrap_root": True,
        "compose_no_deps": True,
        # PostgreSQL is durable state infrastructure. Normal application
        # overlays can rebuild/recreate only these two stateless services.
        "services": ("device-control-core", "device-gateway"),
    },
    "proxy-contur": {
        "payload_root": Path("/volume1/docker/proxy-contur"),
        "compose_root": Path("/volume1/docker/proxy-contur"),
        "compose_project": "proxy-contur",
        "compose_env_file": Path("/volume1/docker/proxy-contur/.env"),
        "compose_files": (
            Path("/volume1/docker/proxy-contur/docker-compose.yml"),
        ),
        "compose_build": True,
        "compose_no_deps": True,
        "services": ("proxy-contur",),
        "health_container": "proxy-contur",
    },
    "dc-amd-proxy": {
        "payload_root": Path("/volume1/docker/dc-amd-proxy"),
        "compose_root": Path("/volume1/docker/dc-amd-proxy"),
        "compose_project": "dc-amd-proxy",
        "bootstrap_root": True,
        "compose_build": True,
        "compose_no_deps": True,
        "services": ("dc-amd-proxy",),
        "health_container": "dc-amd-proxy",
    },
    "dc-cms": {
        "payload_root": Path("/volume1/docker/dc-cms/source"),
        "compose_root": Path("/volume1/docker/dc-cms/source/infra"),
        "compose_env_file": Path("/volume1/docker/dc-cms/source/infra/.env.synology"),
        "compose_files": (
            Path("/volume1/docker/dc-cms/source/infra/docker-compose.yml"),
        ),
        "bootstrap_root": True,
        "compose_build": True,
        "services": ("postgresql-authentik", "authentik-server", "authentik-worker", "authentik-bootstrap", "cms-app", "reverse-proxy"),
        "healthchecks": (
            {
                "url": "http://172.22.0.222:9918/auth/login?returnTo=%2F",
                "headers": {"Host": "cms.dcserve.ru"},
            },
            {
                "url": "http://172.22.0.222:9919/",
                "headers": {"Host": "auth.dcserve.ru"},
            },
        ),
    },
    "dc-cms-site-nodedc": {
        "payload_root": Path("/volume1/docker/dc-cms/sites/nodedc"),
        "compose_root": Path("/volume1/docker/dc-cms/source/infra"),
        "compose_env_file": Path("/volume1/docker/dc-cms/source/infra/.env.synology"),
        "compose_files": (
            Path("/volume1/docker/dc-cms/source/infra/docker-compose.yml"),
        ),
        "compose_no_deps": True,
        "services": ("cms-app", "reverse-proxy"),
        "healthchecks": (
            {
                "url": "http://172.22.0.222:9918/auth/login?returnTo=%2F",
                "headers": {"Host": "cms.dcserve.ru"},
            },
        ),
    },
}


class NoRedirectHandler(urllib.request.HTTPRedirectHandler):
    def redirect_request(self, req, fp, code, msg, headers, newurl):
        return None


NO_REDIRECT_OPENER = urllib.request.build_opener(NoRedirectHandler)


class DeployError(Exception):
    pass


class ReconciliationRequired(DeployError):
    pass


def die(message):
    raise DeployError(message)


def utc_now():
    return datetime.now(timezone.utc).replace(microsecond=0).isoformat()


def stamp():
    return datetime.now().strftime("%Y%m%d-%H%M%S")


def sha256_file(path):
    import hashlib

    h = hashlib.sha256()
    with path.open("rb") as f:
        for chunk in iter(lambda: f.read(1024 * 1024), b""):
            h.update(chunk)
    return h.hexdigest()


def sha256_json_value(value):
    import hashlib

    canonical = json.dumps(
        value,
        ensure_ascii=False,
        sort_keys=True,
        separators=(",", ":"),
    ).encode("utf-8")
    return hashlib.sha256(canonical).hexdigest()


def safe_name(value):
    return re.sub(r"[^A-Za-z0-9._-]", "_", value)


def is_relative_to(child, parent):
    try:
        child.relative_to(parent)
        return True
    except ValueError:
        return False


def ensure_layout():
    for path in (INBOX, APPLIED_DIR, FAILED_DIR, BACKUPS_DIR, STATE_DIR, TMP_DIR, RUNTIME_DIR):
        path.mkdir(parents=True, exist_ok=True)

    for path in (STATE_DIR, BACKUPS_DIR, TMP_DIR, RUNTIME_DIR):
        os.chown(path, 0, 0)
        path.chmod(0o700)

    for path in (APPLIED_DIR, FAILED_DIR):
        os.chown(path, 0, 0)
        path.chmod(0o755)


def ensure_platform_runtime_secret(secret_file, secret_re, label):
    # This is Platform infrastructure state, not a product setting. The
    # root-owned runner creates it once and only explicitly bound service mounts
    # can read it. It must never be copied into an artifact or a shared .env.
    secret_dir = secret_file.parent
    try:
        directory_stat = secret_dir.lstat()
    except FileNotFoundError:
        secret_dir.mkdir(parents=True, exist_ok=False)
        directory_stat = secret_dir.lstat()

    if stat.S_ISLNK(directory_stat.st_mode) or not stat.S_ISDIR(directory_stat.st_mode):
        die(f"{label} secret directory is unsafe: {secret_dir}")
    os.chown(secret_dir, 0, MAP_GATEWAY_RUNTIME_GID)
    secret_dir.chmod(0o710)

    try:
        secret_stat = secret_file.lstat()
    except FileNotFoundError:
        secret_value = secrets.token_urlsafe(48)
        temporary = secret_dir / f".{secret_file.name}.{os.getpid()}.{time.time_ns()}.tmp"
        descriptor = None
        try:
            descriptor = os.open(str(temporary), os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o640)
            os.write(descriptor, f"{secret_value}\n".encode("ascii"))
            os.fsync(descriptor)
            os.fchown(descriptor, 0, MAP_GATEWAY_RUNTIME_GID)
            os.fchmod(descriptor, 0o640)
            os.close(descriptor)
            descriptor = None
            os.replace(temporary, secret_file)
            fsync_directory(secret_dir)
        finally:
            if descriptor is not None:
                os.close(descriptor)
            if temporary.exists():
                temporary.unlink()
        return "created"

    if stat.S_ISLNK(secret_stat.st_mode) or not stat.S_ISREG(secret_stat.st_mode):
        die(f"{label} secret file is unsafe: {secret_file}")
    if secret_stat.st_uid != 0 or secret_stat.st_mode & (stat.S_IWGRP | stat.S_IWOTH):
        die(f"{label} secret file has unsafe ownership or permissions: {secret_file}")
    if secret_stat.st_size > 512:
        die(f"{label} secret file is too large: {secret_file}")
    try:
        secret_value = secret_file.read_text(encoding="ascii").strip()
    except UnicodeDecodeError:
        die(f"{label} secret file is not ascii: {secret_file}")
    if not secret_re.fullmatch(secret_value):
        die(f"{label} secret file has invalid format: {secret_file}")
    os.chown(secret_file, 0, MAP_GATEWAY_RUNTIME_GID)
    secret_file.chmod(0o640)
    return "reused"


def ensure_map_gateway_admin_secret():
    return ensure_platform_runtime_secret(
        MAP_GATEWAY_SECRET_FILE,
        MAP_GATEWAY_SECRET_RE,
        "map gateway",
    )


def read_proxy_contur_token():
    try:
        source_stat = PROXY_CONTUR_ENV_FILE.lstat()
    except FileNotFoundError:
        die("proxy-contur env file is required for Map egress")
    if stat.S_ISLNK(source_stat.st_mode) or not stat.S_ISREG(source_stat.st_mode):
        die("proxy-contur env file is unsafe")
    if source_stat.st_size > 64 * 1024 or source_stat.st_mode & (stat.S_IWGRP | stat.S_IWOTH):
        die("proxy-contur env file has unsafe permissions")
    try:
        lines = PROXY_CONTUR_ENV_FILE.read_text(encoding="utf-8").splitlines()
    except UnicodeDecodeError:
        die("proxy-contur env file is not utf-8")

    value = None
    for raw in lines:
        line = raw.strip()
        if not line or line.startswith("#"):
            continue
        if line.startswith("export "):
            line = line[7:].lstrip()
        if not line.startswith("PROXY_TOKEN="):
            continue
        value = line.partition("=")[2].strip()
        if len(value) >= 2 and value[0] in ("'", '"') and value[-1] == value[0]:
            value = value[1:-1]
        break

    if not value or len(value) > 4096 or any(ord(char) < 33 or ord(char) == 127 for char in value):
        die("proxy-contur PROXY_TOKEN is missing or invalid")
    return value


def sync_map_egress_proxy_secret():
    # The Map Gateway gets a read-only file copy of the existing proxy token.
    # The value is never printed, placed in an artifact, or exposed to Foundry.
    token = read_proxy_contur_token()
    try:
        parent_stat = MAP_GATEWAY_SECRET_DIR.lstat()
    except FileNotFoundError:
        MAP_GATEWAY_SECRET_DIR.mkdir(parents=True, exist_ok=False)
        parent_stat = MAP_GATEWAY_SECRET_DIR.lstat()
    if stat.S_ISLNK(parent_stat.st_mode) or not stat.S_ISDIR(parent_stat.st_mode):
        die(f"map egress parent secret directory is unsafe: {MAP_GATEWAY_SECRET_DIR}")
    os.chown(MAP_GATEWAY_SECRET_DIR, 0, MAP_GATEWAY_RUNTIME_GID)
    MAP_GATEWAY_SECRET_DIR.chmod(0o710)

    if MAP_EGRESS_PROXY_SECRET_FILE.exists() or MAP_EGRESS_PROXY_SECRET_FILE.is_symlink():
        target_stat = MAP_EGRESS_PROXY_SECRET_FILE.lstat()
        if stat.S_ISLNK(target_stat.st_mode) or not stat.S_ISREG(target_stat.st_mode):
            die("map egress proxy secret file is unsafe")

    temporary = MAP_GATEWAY_SECRET_DIR / f".{MAP_EGRESS_PROXY_SECRET_FILE.name}.{os.getpid()}.{time.time_ns()}.tmp"
    descriptor = None
    try:
        descriptor = os.open(str(temporary), os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o640)
        os.write(descriptor, f"{token}\n".encode("utf-8"))
        os.fsync(descriptor)
        os.fchown(descriptor, 0, MAP_GATEWAY_RUNTIME_GID)
        os.fchmod(descriptor, 0o640)
        os.close(descriptor)
        descriptor = None
        os.replace(temporary, MAP_EGRESS_PROXY_SECRET_FILE)
        fsync_directory(MAP_GATEWAY_SECRET_DIR)
    finally:
        if descriptor is not None:
            os.close(descriptor)
        if temporary.exists():
            temporary.unlink()
    return "synced"


def ensure_root_owned_grant_directory(path, label):
    try:
        parent_stat = MAP_GATEWAY_SECRET_DIR.lstat()
    except FileNotFoundError:
        MAP_GATEWAY_SECRET_DIR.mkdir(parents=True, exist_ok=False)
        parent_stat = MAP_GATEWAY_SECRET_DIR.lstat()
    if stat.S_ISLNK(parent_stat.st_mode) or not stat.S_ISDIR(parent_stat.st_mode):
        die(f"{label} parent directory is unsafe: {MAP_GATEWAY_SECRET_DIR}")
    os.chown(MAP_GATEWAY_SECRET_DIR, 0, MAP_GATEWAY_RUNTIME_GID)
    MAP_GATEWAY_SECRET_DIR.chmod(0o710)

    try:
        directory_stat = path.lstat()
    except FileNotFoundError:
        path.mkdir(parents=False, exist_ok=False)
        directory_stat = path.lstat()
    if stat.S_ISLNK(directory_stat.st_mode) or not stat.S_ISDIR(directory_stat.st_mode):
        die(f"{label} directory is unsafe: {path}")
    os.chown(path, 0, 0)
    path.chmod(0o500)

    for entry in path.iterdir():
        entry_stat = entry.lstat()
        if (not re.fullmatch(r"[a-f0-9]{64}", entry.name)
                or stat.S_ISLNK(entry_stat.st_mode)
                or not stat.S_ISREG(entry_stat.st_mode)
                or entry_stat.st_uid != 0
                or entry_stat.st_gid != 0
                or stat.S_IMODE(entry_stat.st_mode) != 0o400
                or entry_stat.st_size < 2
                or entry_stat.st_size > 128 * 1024):
            die(f"{label} record is unsafe: {entry}")


def ensure_external_data_plane_provisioner_secret():
    # Unlike the Map Gateway key, this capability can mint scoped writers.
    # Keep it in an isolated child directory readable only by the dedicated
    # EDP/provisioner uid, never by the shared gid 1000.
    try:
        parent_stat = MAP_GATEWAY_SECRET_DIR.lstat()
    except FileNotFoundError:
        MAP_GATEWAY_SECRET_DIR.mkdir(parents=True, exist_ok=False)
        parent_stat = MAP_GATEWAY_SECRET_DIR.lstat()
    if stat.S_ISLNK(parent_stat.st_mode) or not stat.S_ISDIR(parent_stat.st_mode):
        die(f"external data plane parent secret directory is unsafe: {MAP_GATEWAY_SECRET_DIR}")
    os.chown(MAP_GATEWAY_SECRET_DIR, 0, MAP_GATEWAY_RUNTIME_GID)
    MAP_GATEWAY_SECRET_DIR.chmod(0o710)

    try:
        directory_stat = EXTERNAL_DATA_PLANE_PROVISIONER_SECRET_DIR.lstat()
    except FileNotFoundError:
        EXTERNAL_DATA_PLANE_PROVISIONER_SECRET_DIR.mkdir(parents=False, exist_ok=False)
        directory_stat = EXTERNAL_DATA_PLANE_PROVISIONER_SECRET_DIR.lstat()
    if stat.S_ISLNK(directory_stat.st_mode) or not stat.S_ISDIR(directory_stat.st_mode):
        die(f"external data plane provisioner secret directory is unsafe: {EXTERNAL_DATA_PLANE_PROVISIONER_SECRET_DIR}")
    os.chown(EXTERNAL_DATA_PLANE_PROVISIONER_SECRET_DIR, EXTERNAL_DATA_PLANE_RUNTIME_UID, EXTERNAL_DATA_PLANE_RUNTIME_GID)
    EXTERNAL_DATA_PLANE_PROVISIONER_SECRET_DIR.chmod(0o500)

    try:
        secret_stat = EXTERNAL_DATA_PLANE_PROVISIONER_SECRET_FILE.lstat()
    except FileNotFoundError:
        secret_value = secrets.token_urlsafe(48)
        temporary = EXTERNAL_DATA_PLANE_PROVISIONER_SECRET_DIR / f".{EXTERNAL_DATA_PLANE_PROVISIONER_SECRET_FILE.name}.{os.getpid()}.{time.time_ns()}.tmp"
        descriptor = None
        try:
            descriptor = os.open(str(temporary), os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o400)
            os.write(descriptor, f"{secret_value}\n".encode("ascii"))
            os.fsync(descriptor)
            os.fchown(descriptor, EXTERNAL_DATA_PLANE_RUNTIME_UID, EXTERNAL_DATA_PLANE_RUNTIME_GID)
            os.fchmod(descriptor, 0o400)
            os.close(descriptor)
            descriptor = None
            os.replace(temporary, EXTERNAL_DATA_PLANE_PROVISIONER_SECRET_FILE)
            fsync_directory(EXTERNAL_DATA_PLANE_PROVISIONER_SECRET_DIR)
        finally:
            if descriptor is not None:
                os.close(descriptor)
            if temporary.exists():
                temporary.unlink()
        return "created"

    if stat.S_ISLNK(secret_stat.st_mode) or not stat.S_ISREG(secret_stat.st_mode):
        die(f"external data plane provisioner secret file is unsafe: {EXTERNAL_DATA_PLANE_PROVISIONER_SECRET_FILE}")
    if (secret_stat.st_uid != EXTERNAL_DATA_PLANE_RUNTIME_UID or
            secret_stat.st_gid != EXTERNAL_DATA_PLANE_RUNTIME_GID or
            stat.S_IMODE(secret_stat.st_mode) != 0o400):
        die(f"external data plane provisioner secret file has unsafe ownership or permissions: {EXTERNAL_DATA_PLANE_PROVISIONER_SECRET_FILE}")
    if secret_stat.st_size > 512:
        die(f"external data plane provisioner secret file is too large: {EXTERNAL_DATA_PLANE_PROVISIONER_SECRET_FILE}")
    try:
        secret_value = EXTERNAL_DATA_PLANE_PROVISIONER_SECRET_FILE.read_text(encoding="ascii").strip()
    except UnicodeDecodeError:
        die(f"external data plane provisioner secret file is not ascii: {EXTERNAL_DATA_PLANE_PROVISIONER_SECRET_FILE}")
    if not EXTERNAL_DATA_PLANE_PROVISIONER_SECRET_RE.fullmatch(secret_value):
        die(f"external data plane provisioner secret file has invalid format: {EXTERNAL_DATA_PLANE_PROVISIONER_SECRET_FILE}")
    return "reused"


def resolve_openssl_binary():
    candidate = shutil.which("openssl")
    if not candidate:
        die("openssl is required to provision the Engine credential issuer")
    path = Path(candidate).resolve()
    try:
        path_stat = path.lstat()
    except FileNotFoundError:
        die("resolved openssl binary is missing")
    if (not stat.S_ISREG(path_stat.st_mode)
            or path_stat.st_uid != 0
            or path_stat.st_mode & (stat.S_IWGRP | stat.S_IWOTH)):
        die(f"openssl binary is unsafe: {path}")
    return path


def run_openssl(arguments, label):
    result = subprocess.run(
        [str(resolve_openssl_binary()), *arguments],
        check=False,
        stdin=subprocess.DEVNULL,
        stdout=subprocess.DEVNULL,
        stderr=subprocess.DEVNULL,
        timeout=30,
    )
    if result.returncode != 0:
        die(f"openssl {label} failed")


def validate_ed25519_public_key_file(path):
    try:
        value = path.read_text(encoding="ascii")
    except (OSError, UnicodeDecodeError):
        die(f"Engine credential issuer public key is unreadable: {path}")
    match = re.fullmatch(
        r"-----BEGIN PUBLIC KEY-----\n([A-Za-z0-9+/=\n]+)-----END PUBLIC KEY-----\n?",
        value,
    )
    if not match:
        die("Engine credential issuer public key PEM format mismatch")
    try:
        der = base64.b64decode(match.group(1).replace("\n", ""), validate=True)
    except ValueError:
        die("Engine credential issuer public key base64 is invalid")
    # SubjectPublicKeyInfo for Ed25519 is the fixed RFC 8410 algorithm header
    # plus one 32-byte public key. This rejects accidental RSA/EC key drift
    # without printing either private or public key material.
    if len(der) != 44 or not der.startswith(bytes.fromhex("302a300506032b6570032100")):
        die("Engine credential issuer key is not Ed25519")


def fsync_file(path):
    descriptor = os.open(str(path), os.O_RDONLY)
    try:
        os.fsync(descriptor)
    finally:
        os.close(descriptor)


def ensure_engine_credential_issuer_keypair():
    # The private issuer never enters an artifact, Compose environment or
    # runner output. The Engine receives only its matching public key through
    # the already persistent nodedc-data mount.
    ensure_external_data_plane_provisioner_secret()
    state_dir = ENGINE_CREDENTIAL_SINK_STATE_DIR
    try:
        state_stat = state_dir.lstat()
    except FileNotFoundError:
        state_dir.mkdir(parents=True, exist_ok=False)
        state_stat = state_dir.lstat()
    if stat.S_ISLNK(state_stat.st_mode) or not stat.S_ISDIR(state_stat.st_mode):
        die(f"Engine credential sink state directory is unsafe: {state_dir}")
    os.chown(state_dir, 0, 0)
    state_dir.chmod(0o700)

    private_key = ENGINE_CREDENTIAL_PROVISIONER_PRIVATE_KEY_FILE
    public_key = ENGINE_CREDENTIAL_SINK_PUBLIC_KEY_FILE
    private_exists = private_key.exists() or private_key.is_symlink()
    public_exists = public_key.exists() or public_key.is_symlink()
    if not private_exists and public_exists:
        die("Engine credential issuer public key exists without its private key")

    if private_exists:
        private_stat = private_key.lstat()
        if (stat.S_ISLNK(private_stat.st_mode)
                or not stat.S_ISREG(private_stat.st_mode)
                or private_stat.st_uid != EXTERNAL_DATA_PLANE_RUNTIME_UID
                or private_stat.st_gid != EXTERNAL_DATA_PLANE_RUNTIME_GID
                or stat.S_IMODE(private_stat.st_mode) != 0o400
                or private_stat.st_size < 64
                or private_stat.st_size > 1024):
            die(f"Engine credential issuer private key is unsafe: {private_key}")
        run_openssl(["pkey", "-in", str(private_key), "-noout"], "private key validation")
    else:
        private_tmp = private_key.with_name(f".{private_key.name}.{os.getpid()}.{time.time_ns()}.tmp")
        descriptor = None
        try:
            descriptor = os.open(str(private_tmp), os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o600)
            os.close(descriptor)
            descriptor = None
            run_openssl(["genpkey", "-algorithm", "ED25519", "-out", str(private_tmp)], "Ed25519 key generation")
            os.chown(private_tmp, EXTERNAL_DATA_PLANE_RUNTIME_UID, EXTERNAL_DATA_PLANE_RUNTIME_GID)
            private_tmp.chmod(0o400)
            fsync_file(private_tmp)
            os.replace(private_tmp, private_key)
            fsync_directory(private_key.parent)
        finally:
            if descriptor is not None:
                os.close(descriptor)
            if private_tmp.exists():
                private_tmp.unlink()

    derived_public = state_dir / f".{public_key.name}.{os.getpid()}.{time.time_ns()}.tmp"
    descriptor = None
    try:
        descriptor = os.open(str(derived_public), os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o600)
        os.close(descriptor)
        descriptor = None
        run_openssl(["pkey", "-in", str(private_key), "-pubout", "-out", str(derived_public)], "public key derivation")
        validate_ed25519_public_key_file(derived_public)
        if public_exists:
            public_stat = public_key.lstat()
            if (stat.S_ISLNK(public_stat.st_mode)
                    or not stat.S_ISREG(public_stat.st_mode)
                    or public_stat.st_uid != 0
                    or public_stat.st_gid != 0
                    or stat.S_IMODE(public_stat.st_mode) != 0o444
                    or public_stat.st_size < 64
                    or public_stat.st_size > 1024):
                die(f"Engine credential issuer public key is unsafe: {public_key}")
            validate_ed25519_public_key_file(public_key)
            if derived_public.read_bytes() != public_key.read_bytes():
                die("Engine credential issuer keypair mismatch")
        else:
            os.chown(derived_public, 0, 0)
            derived_public.chmod(0o444)
            fsync_file(derived_public)
            os.replace(derived_public, public_key)
            fsync_directory(state_dir)
    finally:
        if descriptor is not None:
            os.close(descriptor)
        if derived_public.exists():
            derived_public.unlink()
    return "reused" if private_exists else "created"
def ensure_engine_edp_managed_provisioner_keypair():
    # Engine is the sole holder of the signing key. EDP receives only the
    # matching public key from a separate trust directory. Neither file is
    # copied into an artifact, shared .env, n8n container, or L2 graph.
    openssl = shutil.which("openssl")
    if not openssl:
        die("openssl is required to manage the Engine EDP signing key")

    try:
        secret_parent_stat = MAP_GATEWAY_SECRET_DIR.lstat()
    except FileNotFoundError:
        MAP_GATEWAY_SECRET_DIR.mkdir(parents=True, exist_ok=False)
        secret_parent_stat = MAP_GATEWAY_SECRET_DIR.lstat()
    if stat.S_ISLNK(secret_parent_stat.st_mode) or not stat.S_ISDIR(secret_parent_stat.st_mode):
        die("Engine EDP signing key parent directory is unsafe")
    os.chown(MAP_GATEWAY_SECRET_DIR, 0, MAP_GATEWAY_RUNTIME_GID)
    MAP_GATEWAY_SECRET_DIR.chmod(0o710)

    try:
        private_dir_stat = ENGINE_EDP_MANAGED_PROVISIONER_SECRET_DIR.lstat()
    except FileNotFoundError:
        ENGINE_EDP_MANAGED_PROVISIONER_SECRET_DIR.mkdir(parents=False, exist_ok=False)
        private_dir_stat = ENGINE_EDP_MANAGED_PROVISIONER_SECRET_DIR.lstat()
    if stat.S_ISLNK(private_dir_stat.st_mode) or not stat.S_ISDIR(private_dir_stat.st_mode):
        die("Engine EDP signing key directory is unsafe")
    os.chown(ENGINE_EDP_MANAGED_PROVISIONER_SECRET_DIR, 0, 0)
    ENGINE_EDP_MANAGED_PROVISIONER_SECRET_DIR.chmod(0o700)

    trust_parent = ENGINE_EDP_MANAGED_PROVISIONER_TRUST_DIR.parent
    try:
        trust_parent_stat = trust_parent.lstat()
    except FileNotFoundError:
        trust_parent.mkdir(parents=True, exist_ok=False)
        trust_parent_stat = trust_parent.lstat()
    if stat.S_ISLNK(trust_parent_stat.st_mode) or not stat.S_ISDIR(trust_parent_stat.st_mode):
        die("Engine EDP trust parent directory is unsafe")
    os.chown(trust_parent, 0, EXTERNAL_DATA_PLANE_RUNTIME_GID)
    trust_parent.chmod(0o710)

    try:
        trust_dir_stat = ENGINE_EDP_MANAGED_PROVISIONER_TRUST_DIR.lstat()
    except FileNotFoundError:
        ENGINE_EDP_MANAGED_PROVISIONER_TRUST_DIR.mkdir(parents=False, exist_ok=False)
        trust_dir_stat = ENGINE_EDP_MANAGED_PROVISIONER_TRUST_DIR.lstat()
    if stat.S_ISLNK(trust_dir_stat.st_mode) or not stat.S_ISDIR(trust_dir_stat.st_mode):
        die("Engine EDP trust directory is unsafe")
    os.chown(ENGINE_EDP_MANAGED_PROVISIONER_TRUST_DIR, 0, EXTERNAL_DATA_PLANE_RUNTIME_GID)
    ENGINE_EDP_MANAGED_PROVISIONER_TRUST_DIR.chmod(0o550)

    try:
        private_stat = ENGINE_EDP_MANAGED_PROVISIONER_PRIVATE_KEY_FILE.lstat()
    except FileNotFoundError:
        private_stat = None
    try:
        public_stat = ENGINE_EDP_MANAGED_PROVISIONER_PUBLIC_KEY_FILE.lstat()
    except FileNotFoundError:
        public_stat = None
    # A public-only state is ambiguous: replacing its missing private half
    # would silently rotate trust. Fail before creating anything so recovery is
    # an explicit operator decision. Private-only is recoverable by derivation.
    if private_stat is None and public_stat is not None:
        die("Engine EDP public key exists without its private key")

    private_created = False
    if private_stat is None:
        temporary_private = (
            ENGINE_EDP_MANAGED_PROVISIONER_SECRET_DIR
            / f".private-key.{os.getpid()}.{time.time_ns()}.tmp"
        )
        try:
            subprocess.run(
                [openssl, "genpkey", "-algorithm", "ED25519", "-out", str(temporary_private)],
                check=True,
                stdout=subprocess.DEVNULL,
                stderr=subprocess.PIPE,
                text=True,
            )
            temporary_stat = temporary_private.lstat()
            if (stat.S_ISLNK(temporary_stat.st_mode) or not stat.S_ISREG(temporary_stat.st_mode)
                    or temporary_stat.st_size < 80 or temporary_stat.st_size > 8192):
                die("generated Engine EDP private key is invalid")
            os.chown(temporary_private, 0, 0)
            temporary_private.chmod(0o400)
            with temporary_private.open("rb") as handle:
                os.fsync(handle.fileno())
            os.replace(temporary_private, ENGINE_EDP_MANAGED_PROVISIONER_PRIVATE_KEY_FILE)
            fsync_directory(ENGINE_EDP_MANAGED_PROVISIONER_SECRET_DIR)
            private_created = True
        except (OSError, subprocess.CalledProcessError) as error:
            die(f"failed to generate Engine EDP signing key: {type(error).__name__}")
        finally:
            if temporary_private.exists():
                temporary_private.unlink()
        private_stat = ENGINE_EDP_MANAGED_PROVISIONER_PRIVATE_KEY_FILE.lstat()

    if (stat.S_ISLNK(private_stat.st_mode) or not stat.S_ISREG(private_stat.st_mode)
            or private_stat.st_uid != 0 or private_stat.st_gid != 0
            or stat.S_IMODE(private_stat.st_mode) != 0o400
            or private_stat.st_size < 80 or private_stat.st_size > 8192):
        die("Engine EDP private key has unsafe ownership, mode, or size")

    try:
        derived = subprocess.run(
            [openssl, "pkey", "-in", str(ENGINE_EDP_MANAGED_PROVISIONER_PRIVATE_KEY_FILE), "-pubout"],
            check=True,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
        ).stdout
    except (OSError, subprocess.CalledProcessError) as error:
        die(f"Engine EDP private key validation failed: {type(error).__name__}")
    if (not derived.startswith(b"-----BEGIN PUBLIC KEY-----\n")
            or not derived.rstrip().endswith(b"-----END PUBLIC KEY-----")
            or len(derived) > 8192):
        die("derived Engine EDP public key is invalid")
    try:
        derived_der = subprocess.run(
            [
                openssl,
                "pkey",
                "-in",
                str(ENGINE_EDP_MANAGED_PROVISIONER_PRIVATE_KEY_FILE),
                "-pubout",
                "-outform",
                "DER",
            ],
            check=True,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
        ).stdout
    except (OSError, subprocess.CalledProcessError) as error:
        die(f"Engine EDP private key type validation failed: {type(error).__name__}")
    # RFC 8410 Ed25519 SubjectPublicKeyInfo is exactly 44 bytes and carries the
    # OID 1.3.101.112. Reject RSA/EC keys before either runtime can mount them.
    if (len(derived_der) != 44
            or not derived_der.startswith(bytes.fromhex("302a300506032b6570032100"))):
        die("Engine EDP signing key must be Ed25519")

    if public_stat is not None:
        if (stat.S_ISLNK(public_stat.st_mode) or not stat.S_ISREG(public_stat.st_mode)
                or public_stat.st_uid != 0
                or public_stat.st_gid != EXTERNAL_DATA_PLANE_RUNTIME_GID
                or stat.S_IMODE(public_stat.st_mode) != 0o440
                or public_stat.st_size < 80 or public_stat.st_size > 8192):
            die("Engine EDP public key has unsafe ownership, mode, or size")
        installed = ENGINE_EDP_MANAGED_PROVISIONER_PUBLIC_KEY_FILE.read_bytes()
        if installed != derived:
            die("Engine EDP public key does not match the installed private key")
        return "created" if private_created else "reused"

    temporary_public = (
        ENGINE_EDP_MANAGED_PROVISIONER_TRUST_DIR
        / f".public-key.{os.getpid()}.{time.time_ns()}.tmp"
    )
    descriptor = None
    try:
        descriptor = os.open(str(temporary_public), os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o440)
        os.write(descriptor, derived)
        os.fsync(descriptor)
        os.fchown(descriptor, 0, EXTERNAL_DATA_PLANE_RUNTIME_GID)
        os.fchmod(descriptor, 0o440)
        os.close(descriptor)
        descriptor = None
        os.replace(temporary_public, ENGINE_EDP_MANAGED_PROVISIONER_PUBLIC_KEY_FILE)
        fsync_directory(ENGINE_EDP_MANAGED_PROVISIONER_TRUST_DIR)
    finally:
        if descriptor is not None:
            os.close(descriptor)
        if temporary_public.exists():
            temporary_public.unlink()
    return "created"
    return "created"


def ensure_foundry_edp_managed_provisioner_keypair():
    # Foundry receives its own signing identity. It must never reuse or read
    # the Engine private key; EDP trusts the matching public key separately.
    openssl = shutil.which("openssl")
    if not openssl:
        die("openssl is required to manage the Foundry EDP signing key")

    try:
        secret_parent_stat = MAP_GATEWAY_SECRET_DIR.lstat()
    except FileNotFoundError:
        MAP_GATEWAY_SECRET_DIR.mkdir(parents=True, exist_ok=False)
        secret_parent_stat = MAP_GATEWAY_SECRET_DIR.lstat()
    if stat.S_ISLNK(secret_parent_stat.st_mode) or not stat.S_ISDIR(secret_parent_stat.st_mode):
        die("Foundry EDP signing key parent directory is unsafe")
    os.chown(MAP_GATEWAY_SECRET_DIR, 0, MAP_GATEWAY_RUNTIME_GID)
    MAP_GATEWAY_SECRET_DIR.chmod(0o710)

    try:
        private_dir_stat = FOUNDRY_EDP_MANAGED_PROVISIONER_SECRET_DIR.lstat()
    except FileNotFoundError:
        FOUNDRY_EDP_MANAGED_PROVISIONER_SECRET_DIR.mkdir(parents=False, exist_ok=False)
        private_dir_stat = FOUNDRY_EDP_MANAGED_PROVISIONER_SECRET_DIR.lstat()
    if stat.S_ISLNK(private_dir_stat.st_mode) or not stat.S_ISDIR(private_dir_stat.st_mode):
        die("Foundry EDP signing key directory is unsafe")
    os.chown(FOUNDRY_EDP_MANAGED_PROVISIONER_SECRET_DIR, 0, 0)
    FOUNDRY_EDP_MANAGED_PROVISIONER_SECRET_DIR.chmod(0o700)

    trust_parent = FOUNDRY_EDP_MANAGED_PROVISIONER_TRUST_DIR.parent
    try:
        trust_parent_stat = trust_parent.lstat()
    except FileNotFoundError:
        trust_parent.mkdir(parents=True, exist_ok=False)
        trust_parent_stat = trust_parent.lstat()
    if stat.S_ISLNK(trust_parent_stat.st_mode) or not stat.S_ISDIR(trust_parent_stat.st_mode):
        die("Foundry EDP trust parent directory is unsafe")
    os.chown(trust_parent, 0, EXTERNAL_DATA_PLANE_RUNTIME_GID)
    trust_parent.chmod(0o710)

    try:
        trust_dir_stat = FOUNDRY_EDP_MANAGED_PROVISIONER_TRUST_DIR.lstat()
    except FileNotFoundError:
        FOUNDRY_EDP_MANAGED_PROVISIONER_TRUST_DIR.mkdir(parents=False, exist_ok=False)
        trust_dir_stat = FOUNDRY_EDP_MANAGED_PROVISIONER_TRUST_DIR.lstat()
    if stat.S_ISLNK(trust_dir_stat.st_mode) or not stat.S_ISDIR(trust_dir_stat.st_mode):
        die("Foundry EDP trust directory is unsafe")
    os.chown(FOUNDRY_EDP_MANAGED_PROVISIONER_TRUST_DIR, 0, EXTERNAL_DATA_PLANE_RUNTIME_GID)
    FOUNDRY_EDP_MANAGED_PROVISIONER_TRUST_DIR.chmod(0o550)

    try:
        private_stat = FOUNDRY_EDP_MANAGED_PROVISIONER_PRIVATE_KEY_FILE.lstat()
    except FileNotFoundError:
        private_stat = None
    try:
        public_stat = FOUNDRY_EDP_MANAGED_PROVISIONER_PUBLIC_KEY_FILE.lstat()
    except FileNotFoundError:
        public_stat = None
    if private_stat is None and public_stat is not None:
        die("Foundry EDP public key exists without its private key")

    private_created = False
    if private_stat is None:
        temporary_private = (
            FOUNDRY_EDP_MANAGED_PROVISIONER_SECRET_DIR
            / f".private-key.{os.getpid()}.{time.time_ns()}.tmp"
        )
        try:
            subprocess.run(
                [openssl, "genpkey", "-algorithm", "ED25519", "-out", str(temporary_private)],
                check=True,
                stdout=subprocess.DEVNULL,
                stderr=subprocess.PIPE,
                text=True,
            )
            temporary_stat = temporary_private.lstat()
            if (stat.S_ISLNK(temporary_stat.st_mode) or not stat.S_ISREG(temporary_stat.st_mode)
                    or temporary_stat.st_size < 80 or temporary_stat.st_size > 8192):
                die("generated Foundry EDP private key is invalid")
            os.chown(temporary_private, 0, 0)
            temporary_private.chmod(0o400)
            with temporary_private.open("rb") as handle:
                os.fsync(handle.fileno())
            os.replace(temporary_private, FOUNDRY_EDP_MANAGED_PROVISIONER_PRIVATE_KEY_FILE)
            fsync_directory(FOUNDRY_EDP_MANAGED_PROVISIONER_SECRET_DIR)
            private_created = True
        except (OSError, subprocess.CalledProcessError) as error:
            die(f"failed to generate Foundry EDP signing key: {type(error).__name__}")
        finally:
            if temporary_private.exists():
                temporary_private.unlink()
        private_stat = FOUNDRY_EDP_MANAGED_PROVISIONER_PRIVATE_KEY_FILE.lstat()

    if (stat.S_ISLNK(private_stat.st_mode) or not stat.S_ISREG(private_stat.st_mode)
            or private_stat.st_uid != 0 or private_stat.st_gid != 0
            or stat.S_IMODE(private_stat.st_mode) != 0o400
            or private_stat.st_size < 80 or private_stat.st_size > 8192):
        die("Foundry EDP private key has unsafe ownership, mode, or size")

    try:
        derived = subprocess.run(
            [openssl, "pkey", "-in", str(FOUNDRY_EDP_MANAGED_PROVISIONER_PRIVATE_KEY_FILE), "-pubout"],
            check=True,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
        ).stdout
        derived_der = subprocess.run(
            [
                openssl,
                "pkey",
                "-in",
                str(FOUNDRY_EDP_MANAGED_PROVISIONER_PRIVATE_KEY_FILE),
                "-pubout",
                "-outform",
                "DER",
            ],
            check=True,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
        ).stdout
    except (OSError, subprocess.CalledProcessError) as error:
        die(f"Foundry EDP private key validation failed: {type(error).__name__}")
    if (not derived.startswith(b"-----BEGIN PUBLIC KEY-----\n")
            or not derived.rstrip().endswith(b"-----END PUBLIC KEY-----")
            or len(derived) > 8192
            or len(derived_der) != 44
            or not derived_der.startswith(bytes.fromhex("302a300506032b6570032100"))):
        die("Foundry EDP signing key must be Ed25519")

    if public_stat is not None:
        if (stat.S_ISLNK(public_stat.st_mode) or not stat.S_ISREG(public_stat.st_mode)
                or public_stat.st_uid != 0
                or public_stat.st_gid != EXTERNAL_DATA_PLANE_RUNTIME_GID
                or stat.S_IMODE(public_stat.st_mode) != 0o440
                or public_stat.st_size < 80 or public_stat.st_size > 8192):
            die("Foundry EDP public key has unsafe ownership, mode, or size")
        if FOUNDRY_EDP_MANAGED_PROVISIONER_PUBLIC_KEY_FILE.read_bytes() != derived:
            die("Foundry EDP public key does not match the installed private key")
        return "created" if private_created else "reused"

    temporary_public = (
        FOUNDRY_EDP_MANAGED_PROVISIONER_TRUST_DIR
        / f".public-key.{os.getpid()}.{time.time_ns()}.tmp"
    )
    descriptor = None
    try:
        descriptor = os.open(str(temporary_public), os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o440)
        os.write(descriptor, derived)
        os.fsync(descriptor)
        os.fchown(descriptor, 0, EXTERNAL_DATA_PLANE_RUNTIME_GID)
        os.fchmod(descriptor, 0o440)
        os.close(descriptor)
        descriptor = None
        os.replace(temporary_public, FOUNDRY_EDP_MANAGED_PROVISIONER_PUBLIC_KEY_FILE)
        fsync_directory(FOUNDRY_EDP_MANAGED_PROVISIONER_TRUST_DIR)
    finally:
        if descriptor is not None:
            os.close(descriptor)
        if temporary_public.exists():
            temporary_public.unlink()
    return "created"


def ensure_engine_data_product_grant_private_state(include_reader=False):
    # Compose must never create this bind source on our behalf: Docker's normal
    # 0755 directory would either expose control-plane metadata or be rejected
    # by the Engine's fail-closed PublishGrantStore.
    engine_root = component_root("engine")
    try:
        engine_root_stat = engine_root.lstat()
    except FileNotFoundError:
        die("Engine root is missing before private state preparation")
    if stat.S_ISLNK(engine_root_stat.st_mode) or not stat.S_ISDIR(engine_root_stat.st_mode):
        die("Engine root is unsafe before private state preparation")

    state_paths = [
        (engine_root / ENGINE_CONTROL_PLANE_STATE_REL, "Engine control-plane state"),
        (engine_root / ENGINE_PUBLISH_GRANT_STATE_REL, "Engine Publish grant state"),
    ]
    if include_reader:
        state_paths.append((
            engine_root / ENGINE_READ_GRANT_STATE_REL,
            "Engine Read grant state",
        ))
    for state_path, label in state_paths:
        try:
            state_stat = state_path.lstat()
        except FileNotFoundError:
            state_path.mkdir(parents=False, exist_ok=False, mode=0o700)
            state_stat = state_path.lstat()
        if stat.S_ISLNK(state_stat.st_mode) or not stat.S_ISDIR(state_stat.st_mode):
            die(f"{label} directory is unsafe: {state_path}")
        os.chown(state_path, 0, 0)
        state_path.chmod(0o700)
        state_stat = state_path.lstat()
        if (state_stat.st_uid != 0 or state_stat.st_gid != 0
                or stat.S_IMODE(state_stat.st_mode) != 0o700):
            die(f"{label} ownership or mode is unsafe: {state_path}")


def ensure_engine_publish_grant_private_state():
    # Frozen compatibility seam for the established Publish transition.
    return ensure_engine_data_product_grant_private_state(include_reader=False)


def fsync_directory(path):
    descriptor = os.open(str(path), os.O_RDONLY | os.O_DIRECTORY)
    try:
        os.fsync(descriptor)
    finally:
        os.close(descriptor)


def require_root():
    if os.geteuid() != 0:
        die("run with sudo")


def verify_file_mode(path, require_root_owner):
    try:
        st = path.lstat()
    except FileNotFoundError:
        die(f"missing path: {path}")

    if stat.S_ISLNK(st.st_mode):
        die(f"path must not be a symlink: {path}")

    if require_root_owner and (st.st_uid != 0 or st.st_gid != 0):
        die(f"path must be root:root: {path}")

    if st.st_mode & stat.S_IWGRP:
        die(f"path must not be group-writable: {path}")

    if st.st_mode & stat.S_IWOTH:
        die(f"path must not be world-writable: {path}")


def verify_install():
    invoked = Path(sys.argv[0]).absolute()
    if invoked != EXPECTED_SELF:
        die(f"runner must be invoked as {EXPECTED_SELF}, current: {invoked}")

    verify_file_mode(EXPECTED_SELF, require_root_owner=True)
    verify_file_mode(Path("/usr/local"), require_root_owner=True)
    verify_file_mode(Path("/usr/local/sbin"), require_root_owner=True)

    print(f"path={EXPECTED_SELF}")
    print(f"sha256={sha256_file(EXPECTED_SELF)}")
    print(f"python={sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}")
    print("verify-install-ok")


def validate_artifact_location(path):
    if path.suffix != ".tgz":
        die("artifact must have .tgz extension")

    try:
        st = path.lstat()
    except FileNotFoundError:
        die(f"artifact not found: {path}")

    if stat.S_ISLNK(st.st_mode):
        die(f"artifact must not be a symlink: {path}")

    if not stat.S_ISREG(st.st_mode):
        die(f"artifact must be a regular file: {path}")

    if st.st_size > MAX_ARTIFACT_BYTES:
        die(f"artifact too large: {st.st_size} bytes")

    inbox_real = INBOX.resolve()
    parent_real = path.parent.resolve()
    if parent_real != inbox_real:
        die(f"artifact must be inside {INBOX}")

    name = path.name
    if "/" in name or ".." in name or name.startswith("."):
        die(f"unsafe artifact filename: {name}")


def validate_posix_path(value):
    if not value:
        die("empty path")
    if "\\" in value:
        die(f"backslash is not allowed in path: {value}")
    pure = PurePosixPath(value)
    if pure.is_absolute():
        die(f"absolute path rejected: {value}")
    if any(part in ("", ".", "..") for part in pure.parts):
        die(f"path escape rejected: {value}")
    if any(ord(ch) < 32 for ch in value):
        die(f"control character rejected in path: {value!r}")
    return pure


def tar_name_to_path(work_dir, name):
    pure = validate_posix_path(name)
    target = work_dir.joinpath(*pure.parts)
    resolved = target.resolve(strict=False)
    if not is_relative_to(resolved, work_dir.resolve()):
        die(f"tar path escaped work dir: {name}")
    return target


def validate_tar_member(member):
    name = member.name
    validate_posix_path(name)

    if name not in ("manifest.env", "files.txt", "payload") and not name.startswith("payload/"):
        die(f"unexpected tar member: {name}")

    if not (member.isfile() or member.isdir()):
        die(f"unsupported tar member type: {name}")

    if member.mode & stat.S_ISUID or member.mode & stat.S_ISGID:
        die(f"setuid/setgid tar member rejected: {name}")

    if member.isfile() and member.size > MAX_FILE_BYTES:
        die(f"file too large in artifact: {name}")


def scan_tar(artifact):
    member_count = 0
    payload_bytes = 0
    names = set()

    with tarfile.open(artifact, "r:gz") as tar:
        for member in tar:
            member_count += 1
            if member_count > MAX_MEMBER_COUNT:
                die("too many files in artifact")

            validate_tar_member(member)
            if member.name in names:
                die(f"duplicate tar member rejected: {member.name}")
            names.add(member.name)

            if member.isfile() and member.name.startswith("payload/"):
                payload_bytes += member.size
                if payload_bytes > MAX_PAYLOAD_BYTES:
                    die("payload is too large")

    if "manifest.env" not in names:
        die("manifest.env missing")
    if "files.txt" not in names:
        die("files.txt missing")
    if not any(name == "payload" or name.startswith("payload/") for name in names):
        die("payload missing")


def safe_extract(artifact, work_dir):
    scan_tar(artifact)

    with tarfile.open(artifact, "r:gz") as tar:
        for member in tar:
            validate_tar_member(member)
            target = tar_name_to_path(work_dir, member.name)

            if member.isdir():
                target.mkdir(parents=True, exist_ok=True)
                target.chmod(0o755)
                continue

            if target.exists() and target.is_dir():
                die(f"file target already exists as directory: {member.name}")

            target.parent.mkdir(parents=True, exist_ok=True)
            source = tar.extractfile(member)
            if source is None:
                die(f"cannot read tar member: {member.name}")

            tmp = target.with_name(f"{target.name}.extracting")
            with source, tmp.open("wb") as out:
                shutil.copyfileobj(source, out, 1024 * 1024)
            tmp.chmod(0o644)
            os.replace(tmp, target)


def parse_manifest(path):
    data = {}
    with path.open("r", encoding="utf-8") as f:
        for lineno, line in enumerate(f, 1):
            line = line.rstrip("\n")
            if not line:
                continue
            if "=" not in line:
                die(f"manifest line {lineno} must be key=value")
            key, value = line.split("=", 1)
            if key not in MANIFEST_KEYS:
                die(f"unsupported manifest key: {key}")
            if key in data:
                die(f"duplicate manifest key: {key}")
            if any(ord(ch) < 32 for ch in value):
                die(f"control character in manifest value: {key}")
            data[key] = value

    missing = sorted(MANIFEST_KEYS - set(data))
    if missing:
        die(f"manifest keys missing: {', '.join(missing)}")

    if not PATCH_ID_RE.match(data["id"]):
        die("manifest id contains unsafe characters")

    if data["type"] != "app-overlay":
        die(f"unsupported artifact type: {data['type']}")

    if data["component"] not in COMPONENTS:
        die(f"unsupported component: {data['component']}")

    return data


def parse_files_list(path):
    entries = []
    seen = set()
    with path.open("r", encoding="utf-8") as f:
        for lineno, raw in enumerate(f, 1):
            rel = raw.rstrip("\n")
            if not rel:
                continue
            if rel.strip() != rel:
                die(f"files.txt line {lineno} has leading/trailing whitespace")
            validate_posix_path(rel)
            if rel in seen:
                die(f"duplicate files.txt entry: {rel}")
            seen.add(rel)
            entries.append(rel)

    if not entries:
        die("files.txt is empty")

    return entries


def denied_payload_path(component, rel):
    lower = rel.lower()
    parts = lower.split("/")
    base = parts[-1]

    if component == "engine" and rel in (
        "docker-compose.yml",
        "nodedc-source/services/n8n/private-extensions/n8n-nodes-ndc/Dockerfile",
    ):
        pass
    elif component == "platform" and rel in (
        "platform/docker-compose.platform-http.yml",
        "platform/notification-core/Dockerfile",
        "platform/ai-workspace-hub/Dockerfile",
        "platform/ai-workspace-assistant/Dockerfile",
        "platform/ontology-core/Dockerfile",
        "platform/gelios-gateway/Dockerfile",
        "platform/services/map-gateway/Dockerfile",
        "platform/services/external-data-plane/Dockerfile",
    ):
        pass
    elif component == "bim-viewer" and rel in (
        "converter/Dockerfile",
    ):
        pass
    elif component == "dc-cms" and rel in (
        "Dockerfile",
        "infra/docker-compose.yml",
    ):
        pass
    elif component == "module-foundry" and rel in (
        "Dockerfile",
        "infra/docker-compose.module-foundry.yml",
    ):
        pass
    elif component == "device-plane" and rel in (
        "docker-compose.device-plane.yml",
        "services/device-control-core/Dockerfile",
        "services/device-gateway/Dockerfile",
    ):
        pass
    elif component == "proxy-contur" and rel in (
        "Dockerfile",
        "docker-compose.yml",
    ):
        pass
    elif component == "dc-amd-proxy" and rel in (
        "Dockerfile",
        "docker-compose.yml",
    ):
        pass
    elif base in (".env", "dockerfile", "docker-compose.yml", "compose.yml"):
        return "sensitive or infrastructure filename"

    if base.endswith(".env") or base.endswith((".pem", ".crt", ".key", ".p12", ".pfx")):
        return "secret-like file extension"

    if base.endswith((".sh", ".bash", ".zsh")):
        return "shell files are not allowed in app-overlay artifacts"

    if base.endswith(".zip"):
        return "zip backup files are not deployable artifacts"

    if any(part in (".git", "node_modules") for part in parts):
        return "repository/build dependency directory"

    # `packages/tokens` is a versioned UI design-token package, not a secret
    # store. Keep this narrowly scoped exception so the general filename guard
    # remains in force for every other Module Foundry payload path.
    if not (component == "module-foundry" and lower.startswith("packages/tokens/")) and any(
        token in lower for token in ("secret", "token", "password")
    ):
        return "secret-like path"

    runtime_prefixes = ()
    if component == "engine":
        runtime_prefixes = (
            "nodedc-source/server/data",
            "nodedc-source/server/storage",
            "nodedc-source/server/logs",
            "nodedc-source/public/storage",
            "nodedc-source/dist/storage",
        )
        if rel == "nodedc-source/server/.env":
            return "server env file"
    elif component == "launcher":
        runtime_prefixes = (
            "server/data",
            "server/storage",
            "server/logs",
            "public/storage",
            "dist/storage",
        )
        if rel == "server/.env":
            return "server env file"
    elif component == "platform":
        runtime_prefixes = (
            "backups",
            "launcher",
            "ops-agents",
            "tasker",
            "platform/.env.synology",
            "platform/authentik",
            "platform/docs",
            "authentik/data",
            "authentik/certs",
            "authentik/media",
            "authentik/postgresql",
        )
        if rel.startswith("platform/.env"):
            return "platform env file"
        if rel.startswith(("platform/Caddyfile.http.bak", "platform/docker-compose.platform-http.yml.bak")):
            return "platform backup file"
    elif component == "tasker":
        runtime_prefixes = (
            "plane-app/.local-web-root",
            "plane-app/archive",
            "plane-app/backup",
            "plane-app/plane.env",
            "plane-app/plane.env.example",
            "plane-app/plane.env.staging.example",
            "plane-app/plane.env.synology",
            "plane-app/plane.env.synology.base",
            "plane-src/.cache",
            "plane-src/.next",
            "plane-src/.pnpm-store",
            "plane-src/.react-router",
            "plane-src/.turbo",
            "plane-src/build",
            "plane-src/coverage",
            "plane-src/dist",
            "plane-src/playwright-report",
            "plane-src/test-results",
        )
        if rel.startswith(("plane-app/docker-compose.yaml.bak", "plane-app/docker-compose.synology.override.yml.bak")):
            return "tasker backup file"
    elif component == "ops-agents":
        runtime_prefixes = (
            "dist",
        )
        if rel.startswith(".env"):
            return "ops-agents env file"
    elif component == "bim-viewer":
        runtime_prefixes = (
            "dist",
            "frontend/dist",
            "server/data",
            "server/logs",
            "server/storage",
            "server/tmp",
        )
        if rel == ".env" or rel.startswith(".env."):
            if rel != ".env.synology.example":
                return "bim-viewer env file"
        if rel.startswith(("docker-compose.beam.yml.bak",)):
            return "bim-viewer backup file"
    elif component == "module-foundry":
        runtime_prefixes = (
            "runtime-data",
            "node_modules",
            "apps/catalog/dist",
            "server/data",
            "server/logs",
            "server/storage",
        )
        if rel == ".env" or rel.startswith(".env."):
            if rel != ".env.example":
                return "module-foundry env file"
        if rel.startswith(("Dockerfile.bak", "infra/docker-compose.module-foundry.yml.bak")):
            return "module-foundry backup file"
    elif component == "device-plane":
        runtime_prefixes = (
            "runtime",
            "secrets",
            "data",
            "logs",
            "backups",
            "node_modules",
        )
        if rel == ".env" or rel.startswith(".env."):
            return "device-plane env file"
        if "test" in parts:
            return "device-plane test path"
        if rel.startswith((
            "docker-compose.device-plane.yml.bak",
            "services/device-control-core/Dockerfile.bak",
            "services/device-gateway/Dockerfile.bak",
        )):
            return "device-plane backup file"
    elif component == "n8n-private-extension":
        # An extension release is inert data at this boundary. Activation is
        # Engine-owned and must never be smuggled into the artifact as a script,
        # Compose file, environment file, pointer or mount configuration.
        extension_parts = PurePosixPath(rel).parts
        is_release_directory = (
            len(extension_parts) == 3
            and extension_parts[0] == "releases"
            and extension_parts[1] == "n8n-nodes-ndc"
            and N8N_PRIVATE_EXTENSION_RELEASE_RE.fullmatch(extension_parts[2])
        )
        if not is_release_directory and base not in ("package.tgz", "release.json", "rollback.json"):
            return "unexpected private extension release member"
    elif component == "proxy-contur":
        runtime_prefixes = (
            "node_modules",
        )
        if rel == ".env" or rel.startswith(".env."):
            return "proxy-contur env file"
        if rel.startswith(("Dockerfile.bak", "docker-compose.yml.bak")):
            return "proxy-contur backup file"
    elif component == "dc-amd-proxy":
        runtime_prefixes = (
            "node_modules",
            "runtime",
        )
        if rel == ".env" or rel.startswith(".env."):
            return "dc-amd-proxy env file"
        if rel.startswith(("Dockerfile.bak", "docker-compose.yml.bak")):
            return "dc-amd-proxy backup file"
    elif component == "dc-cms":
        runtime_prefixes = (
            "admin/uploads",
            "infra/authentik/certs",
            "infra/authentik/data",
            "infra/authentik/media",
            "infra/authentik/postgresql",
            "server/data",
            "server/logs",
            "server/storage",
            "sites",
        )
        if rel == ".env" or rel.startswith(".env."):
            return "dc-cms root env file"
        if rel in ("infra/.env", "infra/.env.synology"):
            return "dc-cms env file"
        if rel.startswith("infra/.env.") and rel not in (
            "infra/.env.example",
            "infra/.env.synology.example",
        ):
            return "dc-cms env file"
        if rel.startswith(("Dockerfile.bak", "infra/docker-compose.yml.bak")):
            return "dc-cms backup file"
    elif component == "dc-cms-site-nodedc":
        runtime_prefixes = (
            "assets/.trash",
            "assets/uploads/.trash",
            "node_modules",
        )

    if any(rel == prefix or rel.startswith(prefix + "/") for prefix in runtime_prefixes):
        return "runtime data path"

    return None


def allowed_payload_path(component, rel):
    validate_posix_path(rel)
    reason = denied_payload_path(component, rel)
    if reason:
        die(f"path rejected: {rel}: {reason}")

    if component == "engine":
        if rel in ("nodedc-source/package.json", "nodedc-source/package-lock.json"):
            return True
        if rel == "docker-compose.yml":
            return True
        if rel.startswith((
            "nodedc-source/server/",
            "nodedc-source/src/",
            "nodedc-source/dist/",
            "nodedc-source/public/",
            "nodedc-source/workers/ai-workspace-bridge/",
        )):
            return True
        if rel == "nodedc-source/services/n8n/private-extensions" or rel.startswith(
            "nodedc-source/services/n8n/private-extensions/"
        ):
            return True
        if rel == ENGINE_CREDENTIAL_BACKEND_OVERRIDE_TEMPLATE_REL:
            return True
        if rel == ENGINE_DATA_PRODUCT_PUBLISH_GRANT_OVERRIDE_REL:
            return True
        if rel == ENGINE_DATA_PRODUCT_READ_GRANT_OVERRIDE_REL:
            return True
        if rel == ENGINE_NODE_INTELLIGENCE_SERVICE_ROOT_REL or rel.startswith(
            ENGINE_NODE_INTELLIGENCE_SERVICE_ROOT_REL + "/"
        ):
            return True
        if rel == "nodedc-source/dist":
            return True

    if component == "launcher":
        if rel in (
            "index.html",
            "package.json",
            "package-lock.json",
            "tsconfig.json",
            "tsconfig.app.json",
            "tsconfig.node.json",
            "vite.config.ts",
        ):
            return True
        if rel.startswith(("server/", "src/", "public/", "scripts/", "dc-ui-guideline/")):
            return True

    if component == "platform":
        if rel in (
            "platform/Caddyfile.http",
            "platform/docker-compose.platform-http.yml",
            "platform/docker-compose.external-data-plane.yml",
        ):
            return True
        if rel == "platform/notification-core" or rel.startswith("platform/notification-core/"):
            return True
        if rel == "platform/ai-workspace-hub" or rel.startswith("platform/ai-workspace-hub/"):
            return True
        if rel == "platform/ai-workspace-assistant" or rel.startswith("platform/ai-workspace-assistant/"):
            return True
        if rel == "platform/ontology-core" or rel.startswith("platform/ontology-core/"):
            return True
        if rel == "platform/gelios-gateway" or rel.startswith("platform/gelios-gateway/"):
            return True
        if rel == "platform/services/map-gateway" or rel.startswith("platform/services/map-gateway/"):
            return True
        if rel == "platform/services/external-data-plane" or rel.startswith("platform/services/external-data-plane/"):
            return True
        if rel == "platform/packages/external-provider-contract" or rel.startswith("platform/packages/external-provider-contract/"):
            return True
        if rel == "authentik/custom-templates" or rel.startswith("authentik/custom-templates/"):
            return True

    if component == "tasker":
        if rel in (
            "plane-app/docker-compose.yaml",
            "plane-app/docker-compose.synology.override.yml",
        ):
            return True
        if rel.startswith((
            "plane-src/apps/api/",
            "plane-src/apps/web/",
            "plane-src/packages/",
        )):
            return True

    if component == "ops-agents":
        if rel in (
            ".dockerignore",
            ".env.synology.example",
            ".gitignore",
            "Dockerfile",
            "README.md",
            "docker-compose.local.yml",
            "docker-compose.synology.yml",
            "package.json",
            "package-lock.json",
            "tsconfig.json",
        ):
            return True
        if rel.startswith((
            "docs/",
            "migrations/",
            "src/",
        )):
            return True

    if component == "bim-viewer":
        if rel in (
            "converter",
            "embeddedDemos",
            "frontend",
            "images",
            "locales",
            "processor",
            "report",
            "src",
        ):
            return True
        if rel in (
            ".env.synology.example",
            ".esdoc.json",
            ".gitattributes",
            ".gitignore",
            ".release-please-manifest.json",
            "CHANGELOG.md",
            "CODE_OF_CONDUCT.md",
            "LICENSE",
            "README.md",
            "SECURITY.md",
            "_config.yml",
            "changelog-template.hbs",
            "docker-compose.beam.yml",
            "embeddedViewer.html",
            "index.js",
            "package.json",
            "package-lock.json",
            "release-please-config.json",
            "rollup.config.js",
            "rollup.dev.config.js",
            "webComponentExample.html",
            "xeokit-bim-viewer.css",
        ):
            return True
        if rel.startswith((
            "converter/",
            "embeddedDemos/",
            "frontend/",
            "images/",
            "locales/",
            "processor/",
            "report/",
            "server/",
            "src/",
        )):
            return True

    if component == "module-foundry":
        if rel in (
            ".dockerignore",
            ".env.example",
            ".gitignore",
            "Dockerfile",
            "package.json",
            "package-lock.json",
            "tsconfig.base.json",
            "infra/docker-compose.module-foundry.yml",
        ):
            return True
        if rel in ("apps", "packages", "registry", "runtime-seed", "scripts", "server"):
            return True
        if rel.startswith((
            "apps/",
            "packages/",
            "registry/",
            "runtime-seed/",
            "scripts/",
            "server/",
        )):
            return True

    if component == "device-plane":
        if rel in (
            ".dockerignore",
            "package.json",
            "package-lock.json",
            "docker-compose.device-plane.yml",
            DEVICE_PLANE_POSTGRES_BOOTSTRAP_REL,
            "packages/device-protocol-contract",
            "packages/arusnavi-b2-adapter",
            "services/device-control-core",
            "services/device-gateway",
        ):
            return True
        if rel.startswith((
            "packages/device-protocol-contract/",
            "packages/arusnavi-b2-adapter/",
            "services/device-control-core/",
            "services/device-gateway/",
        )):
            return True

    if component == "n8n-private-extension":
        parts = PurePosixPath(rel).parts
        if (
            len(parts) == 3
            and parts[0] == "releases"
            and parts[1] == "n8n-nodes-ndc"
            and N8N_PRIVATE_EXTENSION_RELEASE_RE.fullmatch(parts[2])
        ):
            return True
        if (
            len(parts) == 4
            and parts[0] == "releases"
            and parts[1] == "n8n-nodes-ndc"
            and N8N_PRIVATE_EXTENSION_RELEASE_RE.fullmatch(parts[2])
            and parts[3] in ("package.tgz", "release.json", "rollback.json")
        ):
            return True

    if component == "proxy-contur":
        if rel in (
            "Dockerfile",
            "README.md",
            "docker-compose.yml",
            "package.json",
            "package-lock.json",
            "server.js",
        ):
            return True

    if component == "dc-amd-proxy":
        if rel in (
            "Dockerfile",
            "README.md",
            "docker-compose.yml",
            "package.json",
            "server.mjs",
        ):
            return True

    if component == "dc-cms":
        if rel in (
            ".dockerignore",
            ".gitignore",
            "Dockerfile",
            "README.md",
            "package.json",
            "package-lock.json",
            "infra/.env.example",
            "infra/.env.synology.example",
            "infra/docker-compose.yml",
            "infra/authentik/bootstrap-cms.py",
        ):
            return True
        if rel.startswith((
            "admin/",
            "infra/authentik/custom-templates/",
            "infra/reverse-proxy/",
            "projects/",
            "server/",
        )):
            return True

    if component == "dc-cms-site-nodedc":
        if rel in (
            ".gitignore",
            "README.md",
            "asset-manifest.json",
            "index.html",
            "package.json",
            "package-lock.json",
            "robots.txt",
            "sitemap.xml",
        ):
            return True
        if rel.startswith((
            "assets/",
            "content/",
            "knowledge/",
            "templates/",
            "tools/",
        )):
            return True

    die(f"path allowlist rejected: {rel}")


def path_is_covered_by_files_list(rel, entries):
    return any(rel == entry or rel.startswith(entry.rstrip("/") + "/") for entry in entries)


def validate_payload_tree(component, payload_dir, entries):
    root = payload_dir.resolve()
    for path in payload_dir.rglob("*"):
        resolved = path.resolve(strict=False)
        if not is_relative_to(resolved, root):
            die(f"payload path escaped payload dir: {path}")

        rel = path.relative_to(payload_dir).as_posix()
        if path.is_symlink():
            die(f"payload symlink rejected: {rel}")
        if not path.is_file() and not path.is_dir():
            die(f"payload special file rejected: {rel}")

        if path.is_dir():
            continue

        allowed_payload_path(component, rel)
        if not path_is_covered_by_files_list(rel, entries):
            die(f"payload file is not covered by files.txt: {rel}")


def read_strict_json(path, label, max_bytes=64 * 1024):
    try:
        file_stat = path.lstat()
    except FileNotFoundError:
        die(f"{label} missing: {path}")
    if stat.S_ISLNK(file_stat.st_mode) or not stat.S_ISREG(file_stat.st_mode):
        die(f"{label} must be a regular file")
    if file_stat.st_size < 2 or file_stat.st_size > max_bytes:
        die(f"{label} has invalid size")

    def reject_duplicate_keys(pairs):
        result = {}
        for key, value in pairs:
            if key in result:
                die(f"{label} has duplicate key: {key}")
            result[key] = value
        return result

    try:
        return json.loads(
            path.read_text(encoding="utf-8"),
            object_pairs_hook=reject_duplicate_keys,
        )
    except UnicodeDecodeError:
        die(f"{label} is not utf-8")
    except json.JSONDecodeError as exc:
        die(f"{label} is invalid json: {exc.msg}")


def require_exact_json_keys(value, expected, label):
    if not isinstance(value, dict):
        die(f"{label} must be an object")
    actual = set(value)
    if actual != set(expected):
        die(f"{label} keys mismatch: expected={sorted(expected)} actual={sorted(actual)}")


def validate_n8n_package_tarball(package_path, release):
    package_stat = package_path.lstat()
    if stat.S_ISLNK(package_stat.st_mode) or not stat.S_ISREG(package_stat.st_mode):
        die("private extension package must be a regular file")
    if package_stat.st_size < 1024 or package_stat.st_size > 32 * 1024 * 1024:
        die("private extension package has invalid size")
    if sha256_file(package_path) != release["package"]["sha256"]:
        die("private extension package sha256 mismatch")
    if package_stat.st_size != release["package"]["bytes"]:
        die("private extension package byte count mismatch")

    names = set()
    package_bytes = 0
    package_json_bytes = None
    packed_node_sources = {}
    with tarfile.open(package_path, "r:gz") as archive:
        for member_count, member in enumerate(archive, 1):
            if member_count > 512:
                die("private extension package has too many members")
            validate_posix_path(member.name)
            if member.name in names:
                die(f"duplicate private extension package member: {member.name}")
            names.add(member.name)
            if member.name != "package" and not member.name.startswith("package/"):
                die(f"private extension package member escaped package root: {member.name}")
            if not (member.isfile() or member.isdir()):
                die(f"unsupported private extension package member: {member.name}")
            if member.name == "package":
                if not member.isdir():
                    die("private extension package root must be a directory")
            else:
                package_rel = PurePosixPath(member.name).relative_to("package")
                if any(part.startswith(".") or part.startswith("._") for part in package_rel.parts):
                    die(f"private extension package hidden member rejected: {member.name}")
                if not (
                    package_rel.as_posix() in ("README.md", "package.json")
                    or package_rel.as_posix().startswith("dist/")
                ):
                    die(f"private extension package member is not allowlisted: {member.name}")
            expected_mode = 0o644 if member.isfile() else 0o755
            if stat.S_IMODE(member.mode) != expected_mode:
                die(f"unsafe private extension package mode: {member.name}")
            if member.isfile():
                package_bytes += member.size
                if member.size > 4 * 1024 * 1024 or package_bytes > 64 * 1024 * 1024:
                    die("private extension package payload is too large")
                if member.name == "package/package.json":
                    source = archive.extractfile(member)
                    if source is None:
                        die("private extension package.json cannot be read")
                    package_json_bytes = source.read(64 * 1024 + 1)
                if member.name.startswith("package/dist/nodes/") and member.name.endswith(".node.js"):
                    source = archive.extractfile(member)
                    if source is None:
                        die(f"private extension packed node cannot be read: {member.name}")
                    packed_node_sources[member.name[len("package/"):]] = source.read(4 * 1024 * 1024 + 1)

    if package_json_bytes is None or len(package_json_bytes) > 64 * 1024:
        die("private extension package.json missing or too large")
    try:
        package_json = json.loads(package_json_bytes.decode("utf-8"))
    except (UnicodeDecodeError, json.JSONDecodeError):
        die("private extension package.json is invalid")
    if package_json.get("name") != "n8n-nodes-ndc":
        die("private extension package name mismatch")
    if package_json.get("version") != release["package"]["version"]:
        die("private extension package version mismatch")
    if package_json.get("private") is not True:
        die("private extension package must remain private")
    if package_json.get("dependencies") not in (None, {}):
        die("private extension runtime dependencies are forbidden")
    scripts = package_json.get("scripts") or {}
    if not isinstance(scripts, dict):
        die("private extension package scripts must be an object")
    for lifecycle in ("preinstall", "install", "postinstall", "prepack", "prepare", "postpack"):
        if lifecycle in scripts:
            die(f"private extension lifecycle script is forbidden: {lifecycle}")

    n8n = package_json.get("n8n")
    if not isinstance(n8n, dict):
        die("private extension n8n registration missing")
    registered = []
    expected_registrations = {
        "nodes": N8N_PRIVATE_EXTENSION_NODES,
        "credentials": N8N_PRIVATE_EXTENSION_CREDENTIALS,
    }
    for field, expected in expected_registrations.items():
        values = n8n.get(field)
        if not isinstance(values, list) or not values:
            die(f"private extension n8n.{field} registration missing")
        if values != list(expected):
            die(f"private extension n8n.{field} registration mismatch")
        for value in values:
            if not isinstance(value, str) or not value.startswith("dist/") or value not in names and f"package/{value}" not in names:
                die(f"private extension n8n.{field} member missing: {value}")
            registered.append(value)
    if len(registered) != len(set(registered)):
        die("private extension n8n registration contains duplicates")
    packed_nodes = sorted(
        name[len("package/"):]
        for name in names
        if name.startswith("package/dist/nodes/") and name.endswith(".node.js")
    )
    packed_credentials = sorted(
        name[len("package/"):]
        for name in names
        if name.startswith("package/dist/credentials/") and name.endswith(".credentials.js")
    )
    if packed_nodes != sorted(N8N_PRIVATE_EXTENSION_NODES):
        die("private extension packed node set mismatch")
    if packed_credentials != sorted(N8N_PRIVATE_EXTENSION_CREDENTIALS):
        die("private extension packed credential set mismatch")
    for node_path in N8N_PRIVATE_EXTENSION_NODES:
        source = packed_node_sources.get(node_path)
        if source is None or len(source) > 4 * 1024 * 1024:
            die(f"private extension packed node source missing or too large: {node_path}")
        if b"usableAsTool" in source:
            die(f"private extension packed node would generate a tool variant: {node_path}")


def validate_n8n_private_extension_release(payload_dir, entries):
    if len(entries) != 1:
        die("private extension artifact must contain exactly one immutable release entry")
    release_rel = entries[0]
    parts = PurePosixPath(release_rel).parts
    if (
        len(parts) != 3
        or parts[0] != "releases"
        or parts[1] != "n8n-nodes-ndc"
        or not N8N_PRIVATE_EXTENSION_RELEASE_RE.fullmatch(parts[2])
    ):
        die("private extension files.txt entry must be a digest-bound release directory")

    release_dir = payload_dir / release_rel
    expected_files = {"package.tgz", "release.json", "rollback.json"}
    actual_files = {path.name for path in release_dir.iterdir() if path.is_file()}
    actual_dirs = [path.name for path in release_dir.iterdir() if path.is_dir()]
    if actual_dirs or actual_files != expected_files:
        die("private extension release must contain only package.tgz, release.json and rollback.json")

    release = read_strict_json(release_dir / "release.json", "private extension release manifest")
    require_exact_json_keys(release, ("schemaVersion", "releaseId", "package", "storage", "activation"), "private extension release manifest")
    require_exact_json_keys(release["package"], ("name", "version", "sha256", "bytes", "runtimeTypePrefix"), "private extension package manifest")
    require_exact_json_keys(release["storage"], ("relativePath", "immutable"), "private extension storage manifest")
    require_exact_json_keys(
        release["activation"],
        (
            "owner",
            "status",
            "requiredCommunityPackagePath",
            "requiresAtomicReleaseSwitch",
            "requiresAllN8nProcessesRestart",
            "requiresMcpSchemaAcceptance",
            "rollbackBaselinePolicy",
        ),
        "private extension activation manifest",
    )
    require_exact_json_keys(
        release["activation"]["rollbackBaselinePolicy"],
        ("allowed", "firstActivation", "requiresPreActivationVerification"),
        "private extension rollback baseline policy",
    )

    release_id = parts[2]
    package = release["package"]
    activation = release["activation"]
    if release["schemaVersion"] != "nodedc.n8n-private-extension-release/v2":
        die("private extension release schema mismatch")
    if release["releaseId"] != release_id:
        die("private extension release id mismatch")
    if package["name"] != "n8n-nodes-ndc" or package["runtimeTypePrefix"] != "n8n-nodes-ndc.":
        die("private extension package identity mismatch")
    if not re.fullmatch(r"[0-9]+\.[0-9]+\.[0-9]+", str(package["version"])):
        die("private extension package version is invalid")
    if not re.fullmatch(r"[a-f0-9]{64}", str(package["sha256"])):
        die("private extension package sha256 is invalid")
    if not isinstance(package["bytes"], int) or isinstance(package["bytes"], bool):
        die("private extension package byte count is invalid")
    if release_id != f"{package['version']}-{package['sha256'][:16]}":
        die("private extension release id is not digest-bound")
    if release["storage"] != {"relativePath": release_rel, "immutable": True}:
        die("private extension storage manifest mismatch")
    rollback_baseline_policy = {
        "allowed": [
            "previous_verified_immutable_release",
            "verified_inactive",
        ],
        "firstActivation": "verified_inactive",
        "requiresPreActivationVerification": True,
    }
    if activation != {
        "owner": "engine",
        "status": "blocked_pending_engine_owned_mount",
        "requiredCommunityPackagePath": "/home/node/.n8n/nodes/node_modules/n8n-nodes-ndc",
        "requiresAtomicReleaseSwitch": True,
        "requiresAllN8nProcessesRestart": True,
        "requiresMcpSchemaAcceptance": True,
        "rollbackBaselinePolicy": rollback_baseline_policy,
    }:
        die("private extension activation boundary mismatch")

    rollback = read_strict_json(release_dir / "rollback.json", "private extension rollback manifest")
    require_exact_json_keys(
        rollback,
        ("schemaVersion", "releaseId", "packageSha256", "mode", "baselinePolicy", "steps", "forbidden"),
        "private extension rollback manifest",
    )
    require_exact_json_keys(
        rollback["baselinePolicy"],
        ("allowed", "firstActivation", "requiresPreActivationVerification"),
        "private extension rollback manifest baseline policy",
    )
    if rollback != {
        "schemaVersion": "nodedc.n8n-private-extension-rollback/v2",
        "releaseId": release_id,
        "packageSha256": package["sha256"],
        "mode": "engine-owned-atomic-release-switch",
        "baselinePolicy": rollback_baseline_policy,
        "steps": [
            "select_verified_previous_release_or_preverified_inactive_baseline",
            "switch_engine_owned_mount_atomically",
            "restart_all_n8n_processes",
            "verify_mcp_schema_state_matches_selected_baseline",
        ],
        "forbidden": [
            "delete_active_release",
            "mutate_engine_core",
            "live_npm_install",
        ],
    }:
        die("private extension rollback manifest mismatch")

    validate_n8n_package_tarball(release_dir / "package.tgz", release)


def is_engine_n8n_transition(component, entries):
    return component == "engine" and entries is not None and ENGINE_N8N_TRANSITION_DESCRIPTOR_REL in entries


def engine_n8n_credential_types_for_release(release_id):
    expected = ENGINE_N8N_CREDENTIAL_TYPES_BY_RELEASE.get(release_id)
    if expected is None:
        die("Engine n8n credential catalog release is not registered")
    return expected


def read_engine_n8n_transition_descriptor(path, label="Engine n8n transition descriptor"):
    descriptor = read_strict_json(path, label)
    require_exact_json_keys(
        descriptor,
        (
            "schemaVersion",
            "action",
            "releaseId",
            "packageVersion",
            "packageSha256",
            "n8nVersion",
            "baseImage",
            "baseImageArchitecture",
            "baseImageIdentityPolicy",
            "sealedReleaseRelativePath",
            "composeOverride",
            "runtimePackagePath",
            "topologyServices",
            "expectedCurrent",
            "expectedNodeTypes",
            "expectedCredentialTypes",
            "rollbackBaseline",
        ),
        label,
    )
    action = descriptor.get("action")
    if descriptor.get("schemaVersion") != "nodedc.engine-n8n-private-extension-transition/v1":
        die("Engine n8n transition schema mismatch")
    if action not in ("activate", "rollback-inactive"):
        die("Engine n8n transition action mismatch")
    release_id = descriptor.get("releaseId")
    package_version = descriptor.get("packageVersion")
    package_sha256 = descriptor.get("packageSha256")
    if not isinstance(release_id, str) or not N8N_PRIVATE_EXTENSION_RELEASE_RE.fullmatch(release_id):
        die("Engine n8n transition release id is invalid")
    if not isinstance(package_version, str) or not re.fullmatch(r"[0-9]+\.[0-9]+\.[0-9]+", package_version):
        die("Engine n8n transition package version is invalid")
    if not isinstance(package_sha256, str) or not re.fullmatch(r"[a-f0-9]{64}", package_sha256):
        die("Engine n8n transition package sha256 is invalid")
    if release_id != f"{package_version}-{package_sha256[:16]}":
        die("Engine n8n transition release identity mismatch")
    expected_sealed_path = f"n8n-private-extensions/releases/n8n-nodes-ndc/{release_id}/package"
    exact_common = {
        "n8nVersion": ENGINE_N8N_VERSION,
        "baseImage": ENGINE_N8N_BASE_IMAGE,
        "baseImageArchitecture": ENGINE_N8N_BASE_ARCHITECTURE,
        "baseImageIdentityPolicy": "running-container-and-local-tag-must-match",
        "sealedReleaseRelativePath": expected_sealed_path,
        "composeOverride": ENGINE_N8N_COMPOSE_OVERRIDE_REL,
        "runtimePackagePath": ENGINE_N8N_RUNTIME_PACKAGE_PATH,
        "topologyServices": ["n8n"],
    }
    for key, expected in exact_common.items():
        if descriptor.get(key) != expected:
            die(f"Engine n8n transition {key} mismatch")
    if action == "activate":
        expected_current = descriptor.get("expectedCurrent")
        if (
            expected_current != "verified_inactive"
            and expected_current not in ENGINE_N8N_RELEASE_CATALOG_JSON_SHA256
        ):
            die("Engine n8n activation expected-current release is not registered")
        if expected_current == release_id:
            die("Engine n8n activation target already equals expected current")
        if descriptor.get("rollbackBaseline") != expected_current:
            die("Engine n8n activation rollback baseline mismatch")
        if descriptor.get("expectedNodeTypes") != list(ENGINE_N8N_NODE_TYPES):
            die("Engine n8n activation node type set mismatch")
        if descriptor.get("expectedCredentialTypes") != list(
            engine_n8n_credential_types_for_release(release_id)
        ):
            die("Engine n8n activation credential type set mismatch")
    else:
        if descriptor.get("expectedCurrent") != release_id:
            die("Engine n8n rollback expected-current release mismatch")
        if descriptor.get("rollbackBaseline") != "verified_inactive":
            die("Engine n8n inactive rollback baseline mismatch")
        if descriptor.get("expectedNodeTypes") != [] or descriptor.get("expectedCredentialTypes") != []:
            die("Engine n8n rollback must select the inactive catalog")
    return descriptor


def expected_engine_n8n_compose_override(descriptor):
    health_script = (
        "const http=require('http');const req=http.get('http://127.0.0.1:5678/healthz/readiness',"
        "r=>{r.resume();process.exit(r.statusCode===200?0:1)});req.on('error',()=>process.exit(1));"
        "req.setTimeout(4000,()=>{req.destroy();process.exit(1)});"
    )
    health_test = json.dumps(["CMD", "node", "-e", health_script], separators=(",", ":"))
    mount_source = f"/volume2/nodedc-demo/{descriptor['sealedReleaseRelativePath']}"
    return "\n".join((
        "services:",
        "  n8n:",
        f"    image: {ENGINE_N8N_BASE_IMAGE}",
        "    platform: linux/amd64",
        "    pull_policy: never",
        "    environment:",
        "      N8N_USER_FOLDER: /home/node",
        '      N8N_COMMUNITY_PACKAGES_ENABLED: "true"',
        '      N8N_COMMUNITY_PACKAGES_PREVENT_LOADING: "false"',
        '      N8N_REINSTALL_MISSING_PACKAGES: "false"',
        "    volumes:",
        f"      - {mount_source}:{ENGINE_N8N_RUNTIME_PACKAGE_PATH}:ro",
        "    healthcheck:",
        f"      test: {health_test}",
        "      interval: 10s",
        "      timeout: 5s",
        "      retries: 30",
        "      start_period: 30s",
        "    labels:",
        f"      nodedc.n8n-private-extension.release: {descriptor['releaseId']}",
        f"      nodedc.n8n-private-extension.package-sha256: {descriptor['packageSha256']}",
        "",
    ))


def validate_engine_n8n_catalog_payload(payload_dir, descriptor):
    action = descriptor["action"]
    nodes_path = payload_dir / ENGINE_N8N_NODES_CATALOG_REL
    credentials_path = payload_dir / ENGINE_N8N_CREDENTIALS_CATALOG_REL
    meta_path = payload_dir / ENGINE_N8N_SCHEMA_META_REL
    nodes = read_strict_json(
        nodes_path,
        "Engine n8n node catalog",
        max_bytes=32 * 1024 * 1024,
    )
    credentials = read_strict_json(
        credentials_path,
        "Engine n8n credential catalog",
        max_bytes=4 * 1024 * 1024,
    )
    meta = read_strict_json(meta_path, "Engine n8n schema metadata")
    if not isinstance(nodes, list) or not isinstance(credentials, list):
        die("Engine n8n schema catalogs must be arrays")
    private_nodes = [
        item for item in nodes
        if isinstance(item, dict) and str(item.get("name") or "").startswith("n8n-nodes-ndc.")
    ]
    private_credentials = [
        item for item in credentials
        if isinstance(item, dict) and str(item.get("name") or "") in ENGINE_N8N_CREDENTIAL_TYPES
    ]
    expected_node_types = list(ENGINE_N8N_NODE_TYPES) if action == "activate" else []
    expected_credential_types = (
        list(engine_n8n_credential_types_for_release(descriptor["releaseId"]))
        if action == "activate"
        else []
    )
    if [item.get("name") for item in private_nodes] != expected_node_types:
        die("Engine n8n pinned node catalog exact set mismatch")
    if [item.get("name") for item in private_credentials] != expected_credential_types:
        die("Engine n8n pinned credential catalog exact set mismatch")
    if any("usableAsTool" in item for item in private_nodes):
        die("Engine n8n pinned node catalog would generate tool variants")
    if action == "activate":
        if len(nodes) != 437 or len(credentials) != 385 + len(expected_credential_types):
            die("Engine n8n activation catalog count mismatch")
        if any(not str(item.get("displayName") or "").startswith("NDC ") for item in private_nodes):
            die("Engine n8n private node visible name mismatch")
        if any(not str(item.get("displayName") or "").startswith("NDC ") for item in private_credentials):
            die("Engine n8n private credential visible name mismatch")
        private_catalog_text = json.dumps(
            {"nodes": private_nodes, "credentials": private_credentials},
            ensure_ascii=False,
        ).lower()
        if "gelios" in private_catalog_text or "robot2b" in private_catalog_text:
            die("provider business identity is forbidden in the Engine n8n extension catalog")
    else:
        if len(nodes) != 434 or len(credentials) != 385:
            die("Engine n8n inactive baseline catalog count mismatch")
    if not isinstance(meta, dict):
        die("Engine n8n schema metadata must be an object")
    if meta.get("n8nVersion") != ENGINE_N8N_VERSION:
        die("Engine n8n schema metadata version mismatch")
    if meta.get("nodeCount") != len(nodes) or meta.get("credentialCount") != len(credentials):
        die("Engine n8n schema metadata count mismatch")
    if action == "activate":
        if meta.get("source") != f"n8n-core+n8n-nodes-ndc@{descriptor['packageVersion']}":
            die("Engine n8n schema metadata source mismatch")
        if sha256_file(payload_dir / ENGINE_N8N_ICON_REL) != ENGINE_N8N_ICON_SHA256:
            die("Engine n8n light icon sha256 mismatch")
        if sha256_file(payload_dir / ENGINE_N8N_DARK_ICON_REL) != ENGINE_N8N_DARK_ICON_SHA256:
            die("Engine n8n dark icon sha256 mismatch")
        release_hashes = ENGINE_N8N_RELEASE_CATALOG_JSON_SHA256.get(descriptor["releaseId"])
        if release_hashes is None:
            die("Engine n8n activation release catalog is not registered")
        expected_catalog_hashes = (
            (nodes, release_hashes["nodes"], "node"),
            (credentials, release_hashes["credentials"], "credential"),
            (meta, release_hashes["meta"], "metadata"),
        )
    else:
        expected_catalog_hashes = (
            (nodes, ENGINE_N8N_INACTIVE_NODES_CATALOG_JSON_SHA256, "node"),
            (credentials, ENGINE_N8N_INACTIVE_CREDENTIALS_CATALOG_JSON_SHA256, "credential"),
            (meta, ENGINE_N8N_INACTIVE_META_JSON_SHA256, "metadata"),
        )
    for catalog, expected_sha256, label in expected_catalog_hashes:
        if sha256_json_value(catalog) != expected_sha256:
            die(f"Engine n8n {action} {label} catalog sha256 mismatch")


def validate_engine_n8n_transition(payload_dir, entries):
    descriptor = read_engine_n8n_transition_descriptor(payload_dir / ENGINE_N8N_TRANSITION_DESCRIPTOR_REL)
    activation_entries = [
        ENGINE_N8N_TRANSITION_DESCRIPTOR_REL,
        ENGINE_N8N_COMPOSE_OVERRIDE_REL,
        ENGINE_N8N_NODES_CATALOG_REL,
        ENGINE_N8N_CREDENTIALS_CATALOG_REL,
        ENGINE_N8N_SCHEMA_META_REL,
        ENGINE_N8N_ICON_REL,
        ENGINE_N8N_DARK_ICON_REL,
    ]
    rollback_entries = [
        ENGINE_N8N_TRANSITION_DESCRIPTOR_REL,
        ENGINE_N8N_NODES_CATALOG_REL,
        ENGINE_N8N_CREDENTIALS_CATALOG_REL,
        ENGINE_N8N_SCHEMA_META_REL,
    ]
    expected_entries = activation_entries if descriptor["action"] == "activate" else rollback_entries
    if entries != expected_entries:
        die("Engine n8n transition files.txt exact set/order mismatch")
    if descriptor["action"] == "activate":
        override = payload_dir / ENGINE_N8N_COMPOSE_OVERRIDE_REL
        try:
            override_text = override.read_text(encoding="utf-8")
        except (OSError, UnicodeDecodeError):
            die("Engine n8n Compose override cannot be read")
        if override_text != expected_engine_n8n_compose_override(descriptor):
            die("Engine n8n Compose override mismatch")
        if "N8N_CUSTOM_EXTENSIONS" in override_text or "CUSTOM." in override_text:
            die("Engine n8n custom-extension loader is forbidden")
    validate_engine_n8n_catalog_payload(payload_dir, descriptor)
    return descriptor


def is_engine_node_intelligence_transition(component, entries):
    if component != "engine" or entries is None:
        return False
    return tuple(entries) in (
        ENGINE_NODE_INTELLIGENCE_ARTIFACT_ENTRIES,
        ENGINE_NODE_INTELLIGENCE_ROLLBACK_ENTRIES,
    )


def expected_engine_node_intelligence_compose_override():
    return "\n".join((
        "services:",
        f"  {ENGINE_NODE_INTELLIGENCE_SERVICE}:",
        f"    image: {ENGINE_NODE_INTELLIGENCE_IMAGE}",
        "    pull_policy: never",
        "    restart: unless-stopped",
        f'    user: "{ENGINE_NODE_INTELLIGENCE_RUNTIME_UID}:{ENGINE_NODE_INTELLIGENCE_RUNTIME_GID}"',
        "    read_only: true",
        "    environment:",
        "      HOME: /tmp",
        "      NODE_ENV: production",
        "      MCP_MODE: http",
        '      PORT: "3000"',
        f"      AUTH_TOKEN_FILE: {ENGINE_NODE_INTELLIGENCE_SECRET_CONTAINER_PATH}",
        "      NODE_DB_PATH: /app/data/nodes.db",
        '      REBUILD_ON_START: "false"',
        '      N8N_MCP_TELEMETRY_DISABLED: "true"',
        "      LOG_LEVEL: warn",
        "    volumes:",
        "      - type: bind",
        f"        source: {ENGINE_NODE_INTELLIGENCE_SECRET_FILE}",
        f"        target: {ENGINE_NODE_INTELLIGENCE_SECRET_CONTAINER_PATH}",
        "        read_only: true",
        "    expose:",
        '      - "3000"',
        "    tmpfs:",
        "      - /tmp:mode=1777",
        "      - /app/logs:mode=0755",
        "    cap_drop:",
        "      - ALL",
        "    security_opt:",
        "      - no-new-privileges:true",
        "    healthcheck:",
        "      test:",
        "        - CMD-SHELL",
        "        - curl -fsS http://127.0.0.1:3000/health >/dev/null",
        "      interval: 15s",
        "      timeout: 5s",
        "      retries: 10",
        "      start_period: 30s",
        "",
        "  nodedc-backend:",
        "    depends_on:",
        f"      {ENGINE_NODE_INTELLIGENCE_SERVICE}:",
        "        condition: service_healthy",
        "    environment:",
        f"      ENGINE_NODE_INTELLIGENCE_MCP_URL: http://{ENGINE_NODE_INTELLIGENCE_SERVICE}:3000/mcp",
        f"      ENGINE_NODE_INTELLIGENCE_AUTH_TOKEN_FILE: {ENGINE_NODE_INTELLIGENCE_SECRET_CONTAINER_PATH}",
        f"      ENGINE_NODE_INTELLIGENCE_ASSET_ID: nodedc-node-intelligence@{ENGINE_NODE_INTELLIGENCE_RELEASE_ID.replace('-', '+', 1)}",
        "    volumes:",
        "      - type: bind",
        f"        source: {ENGINE_NODE_INTELLIGENCE_SECRET_FILE}",
        f"        target: {ENGINE_NODE_INTELLIGENCE_SECRET_CONTAINER_PATH}",
        "        read_only: true",
        "",
    ))


def read_engine_node_intelligence_descriptor(path, label="Engine node-intelligence descriptor"):
    descriptor = read_strict_json(path, label)
    require_exact_json_keys(
        descriptor,
        (
            "schemaVersion",
            "action",
            "releaseId",
            "expectedCurrent",
            "upstream",
            "image",
            "source",
            "predecessor",
        ),
        label,
    )
    if descriptor.get("schemaVersion") != "nodedc.engine-node-intelligence-transition/v1":
        die("Engine node-intelligence transition schema mismatch")
    action = descriptor.get("action")
    if action not in ("activate", "rollback-inactive"):
        die("Engine node-intelligence transition action mismatch")
    if descriptor.get("releaseId") != ENGINE_NODE_INTELLIGENCE_RELEASE_ID:
        die("Engine node-intelligence release mismatch")
    require_exact_json_keys(
        descriptor.get("upstream"),
        ("package", "version", "commit"),
        f"{label} upstream",
    )
    if descriptor["upstream"] != {
        "package": "n8n-mcp",
        "version": "2.33.2",
        "commit": ENGINE_NODE_INTELLIGENCE_UPSTREAM_COMMIT,
    }:
        die("Engine node-intelligence upstream pin mismatch")
    require_exact_json_keys(
        descriptor.get("predecessor"),
        ("gatewaySha256", "composeSha256", "backendRuntime"),
        f"{label} predecessor",
    )
    predecessor = descriptor["predecessor"]
    if predecessor.get("composeSha256") != ENGINE_NODE_INTELLIGENCE_PREDECESSOR_COMPOSE_SHA256:
        die("Engine node-intelligence predecessor Compose mismatch")
    if predecessor.get("backendRuntime") != "verified-derived-retry":
        die("Engine node-intelligence backend predecessor mismatch")

    if action == "activate":
        if descriptor.get("expectedCurrent") != "inactive":
            die("Engine node-intelligence activation expected-current mismatch")
        if predecessor.get("gatewaySha256") != ENGINE_NODE_INTELLIGENCE_PREDECESSOR_GATEWAY_SHA256:
            die("Engine node-intelligence activation gateway predecessor mismatch")
        require_exact_json_keys(
            descriptor.get("image"),
            (
                "tag",
                "archiveRelativePath",
                "archiveSha256",
                "configSha256",
                "architecture",
                "os",
            ),
            f"{label} image",
        )
        image = descriptor["image"]
        if (
            image.get("tag") != ENGINE_NODE_INTELLIGENCE_IMAGE
            or image.get("archiveRelativePath") != ENGINE_NODE_INTELLIGENCE_IMAGE_ARCHIVE_REL
            or not re.fullmatch(r"[a-f0-9]{64}", str(image.get("archiveSha256") or ""))
            or not re.fullmatch(r"[a-f0-9]{64}", str(image.get("configSha256") or ""))
            or image.get("architecture") != "amd64"
            or image.get("os") != "linux"
        ):
            die("Engine node-intelligence image descriptor mismatch")
        require_exact_json_keys(
            descriptor.get("source"),
            (
                "gatewaySha256",
                "catalogSha256",
                "upstreamClientSha256",
                "upstreamProjectionSha256",
                "composeOverrideSha256",
                "readmeSha256",
            ),
            f"{label} source",
        )
        for value in descriptor["source"].values():
            if not re.fullmatch(r"[a-f0-9]{64}", str(value or "")):
                die("Engine node-intelligence source digest is invalid")
    else:
        if descriptor.get("expectedCurrent") != ENGINE_NODE_INTELLIGENCE_RELEASE_ID:
            die("Engine node-intelligence rollback expected-current mismatch")
        require_exact_json_keys(
            descriptor.get("image"),
            ("tag", "configSha256", "architecture", "os"),
            f"{label} image",
        )
        image = descriptor["image"]
        if (
            image.get("tag") != ENGINE_NODE_INTELLIGENCE_IMAGE
            or not re.fullmatch(r"[a-f0-9]{64}", str(image.get("configSha256") or ""))
            or image.get("architecture") != "amd64"
            or image.get("os") != "linux"
        ):
            die("Engine node-intelligence rollback image descriptor mismatch")
        require_exact_json_keys(
            descriptor.get("source"),
            ("gatewaySha256", "readmeSha256"),
            f"{label} source",
        )
        if descriptor["source"].get("gatewaySha256") != ENGINE_NODE_INTELLIGENCE_PREDECESSOR_GATEWAY_SHA256:
            die("Engine node-intelligence rollback gateway target mismatch")
        if any(
            not re.fullmatch(r"[a-f0-9]{64}", str(value or ""))
            for value in descriptor["source"].values()
        ):
            die("Engine node-intelligence rollback source digest is invalid")
        if not re.fullmatch(r"[a-f0-9]{64}", str(predecessor.get("gatewaySha256") or "")):
            die("Engine node-intelligence rollback predecessor gateway is invalid")
    return descriptor


def validate_engine_node_intelligence_image_archive(path, descriptor):
    image = descriptor["image"]
    try:
        archive_stat = path.lstat()
    except FileNotFoundError:
        die("Engine node-intelligence image archive is missing")
    if stat.S_ISLNK(archive_stat.st_mode) or not stat.S_ISREG(archive_stat.st_mode):
        die("Engine node-intelligence image archive is unsafe")
    if archive_stat.st_size < 1024 or archive_stat.st_size > MAX_ARTIFACT_BYTES:
        die("Engine node-intelligence image archive size is invalid")
    if sha256_file(path) != image["archiveSha256"]:
        die("Engine node-intelligence image archive sha256 mismatch")

    names = set()
    manifest_raw = None
    config_raw = None
    total = 0
    try:
        with tarfile.open(path, "r:") as archive:
            members = archive.getmembers()
            if not members or len(members) > MAX_MEMBER_COUNT:
                die("Engine node-intelligence image archive member count is invalid")
            for member in members:
                validate_posix_path(member.name.rstrip("/"))
                if member.name in names:
                    die(f"Engine node-intelligence image archive duplicate member: {member.name}")
                names.add(member.name)
                if not (member.isfile() or member.isdir()):
                    die(f"Engine node-intelligence image archive special member: {member.name}")
                if member.isdir():
                    continue
                if member.size > MAX_FILE_BYTES:
                    die(f"Engine node-intelligence image archive member too large: {member.name}")
                total += member.size
                if total > MAX_ARTIFACT_BYTES:
                    die("Engine node-intelligence image archive expanded size is too large")
                source = archive.extractfile(member)
                if source is None:
                    die(f"Engine node-intelligence image archive member unreadable: {member.name}")
                data = source.read(MAX_FILE_BYTES + 1)
                if len(data) != member.size:
                    die(f"Engine node-intelligence image archive member size mismatch: {member.name}")
                if member.name.startswith("blobs/sha256/"):
                    digest = member.name.rsplit("/", 1)[-1]
                    if not re.fullmatch(r"[a-f0-9]{64}", digest):
                        die("Engine node-intelligence image blob name is invalid")
                    if hashlib.sha256(data).hexdigest() != digest:
                        die("Engine node-intelligence image blob digest mismatch")
                elif member.name not in ("index.json", "manifest.json", "oci-layout"):
                    die(f"Engine node-intelligence image archive unexpected member: {member.name}")
                if member.name == "manifest.json":
                    manifest_raw = data
            if manifest_raw is None:
                die("Engine node-intelligence image manifest is missing")
            try:
                manifest = json.loads(manifest_raw.decode("utf-8"))
            except (UnicodeDecodeError, json.JSONDecodeError):
                die("Engine node-intelligence image manifest is invalid")
            if not isinstance(manifest, list) or len(manifest) != 1:
                die("Engine node-intelligence image manifest exact set mismatch")
            record = manifest[0]
            if not isinstance(record, dict) or set(record) != {"Config", "RepoTags", "Layers"}:
                die("Engine node-intelligence image manifest record mismatch")
            if record.get("RepoTags") != [ENGINE_NODE_INTELLIGENCE_IMAGE]:
                die("Engine node-intelligence image tag mismatch")
            config_name = record.get("Config")
            expected_config_name = f"blobs/sha256/{image['configSha256']}"
            if config_name != expected_config_name:
                die("Engine node-intelligence image config digest mismatch")
            try:
                config_member = archive.getmember(config_name)
                config_file = archive.extractfile(config_member)
                config_raw = config_file.read(MAX_FILE_BYTES + 1) if config_file else None
            except KeyError:
                config_raw = None
    except (tarfile.TarError, OSError):
        die("Engine node-intelligence image archive cannot be read")
    if config_raw is None:
        die("Engine node-intelligence image config is missing")
    try:
        config = json.loads(config_raw.decode("utf-8"))
    except (UnicodeDecodeError, json.JSONDecodeError):
        die("Engine node-intelligence image config is invalid")
    if config.get("architecture") != "amd64" or config.get("os") != "linux":
        die("Engine node-intelligence image platform mismatch")
    runtime_config = config.get("config") or {}
    labels = runtime_config.get("Labels") or {}
    if labels.get("org.opencontainers.image.revision") != ENGINE_NODE_INTELLIGENCE_UPSTREAM_COMMIT:
        die("Engine node-intelligence image revision label mismatch")
    if runtime_config.get("Entrypoint") != ["/usr/local/bin/docker-entrypoint.sh"]:
        die("Engine node-intelligence image entrypoint mismatch")
    if runtime_config.get("Cmd") != ["node", "dist/mcp/index.js"]:
        die("Engine node-intelligence image command mismatch")
    env = runtime_config.get("Env") or []
    if any(
        str(value).startswith(("AUTH_TOKEN=", "N8N_API_URL=", "N8N_API_KEY="))
        for value in env
    ):
        die("Engine node-intelligence image contains runtime authority")
    return image["configSha256"]


def validate_engine_node_intelligence_transition(payload_dir, entries):
    service_root = payload_dir / ENGINE_NODE_INTELLIGENCE_SERVICE_ROOT_REL
    descriptor = read_engine_node_intelligence_descriptor(
        service_root / "activation.json"
    )
    expected_entries = (
        ENGINE_NODE_INTELLIGENCE_ARTIFACT_ENTRIES
        if descriptor["action"] == "activate"
        else ENGINE_NODE_INTELLIGENCE_ROLLBACK_ENTRIES
    )
    if tuple(entries) != expected_entries:
        die("Engine node-intelligence files.txt exact set/order mismatch")
    gateway = payload_dir / ENGINE_NODE_INTELLIGENCE_GATEWAY_REL
    if sha256_file(gateway) != descriptor["source"]["gatewaySha256"]:
        die("Engine node-intelligence gateway sha256 mismatch")
    readme = service_root / "README.md"
    if sha256_file(readme) != descriptor["source"]["readmeSha256"]:
        die("Engine node-intelligence README sha256 mismatch")

    if descriptor["action"] == "activate":
        expected_service_files = {
            "README.md",
            "activation.json",
            "docker-compose.immutable-runtime.yml",
            "image/engine-node-intelligence.tar",
        }
        actual_service_files = {
            child.relative_to(service_root).as_posix()
            for child in service_root.rglob("*")
            if child.is_file()
        }
        if actual_service_files != expected_service_files:
            die("Engine node-intelligence service payload file set mismatch")
        source_root = payload_dir / ENGINE_NODE_INTELLIGENCE_SOURCE_REL
        expected_source_files = {
            "catalog.js",
            "upstreamMcpClient.js",
            "upstreamProjection.js",
        }
        actual_source_files = {
            child.relative_to(source_root).as_posix()
            for child in source_root.rglob("*")
            if child.is_file()
        }
        if actual_source_files != expected_source_files:
            die("Engine node-intelligence source file set mismatch")
        source_digests = {
            "catalogSha256": sha256_file(source_root / "catalog.js"),
            "upstreamClientSha256": sha256_file(source_root / "upstreamMcpClient.js"),
            "upstreamProjectionSha256": sha256_file(source_root / "upstreamProjection.js"),
        }
        if any(descriptor["source"][key] != value for key, value in source_digests.items()):
            die("Engine node-intelligence source digest mismatch")
        override = service_root / "docker-compose.immutable-runtime.yml"
        try:
            override_text = override.read_text(encoding="utf-8")
        except (OSError, UnicodeDecodeError):
            die("Engine node-intelligence Compose override is unreadable")
        if override_text != expected_engine_node_intelligence_compose_override():
            die("Engine node-intelligence Compose override mismatch")
        if sha256_file(override) != descriptor["source"]["composeOverrideSha256"]:
            die("Engine node-intelligence Compose override sha256 mismatch")
        gateway_text = gateway.read_text(encoding="utf-8")
        for required in (
            "engine_get_node_intelligence_status",
            "engine_get_node_guidance",
            "engine_validate_node_configuration",
            "engine_validate_l2_deep",
        ):
            if required not in gateway_text:
                die(f"Engine node-intelligence gateway contract missing: {required}")
        if not any(
            version in gateway_text
            for version in (
                "const ENGINE_AGENT_MCP_VERSION = '0.3.0'",
                "const ENGINE_AGENT_MCP_VERSION = '0.4.0'",
                "const ENGINE_AGENT_MCP_VERSION = '0.5.0'",
                "const ENGINE_AGENT_MCP_VERSION = '0.6.0'",
                "const ENGINE_AGENT_MCP_VERSION = '0.7.0'",
                "const ENGINE_AGENT_MCP_VERSION = '0.8.0'",
                "const ENGINE_AGENT_MCP_VERSION = '0.9.0'",
                "const ENGINE_AGENT_MCP_VERSION = '0.10.0'",
                "const ENGINE_AGENT_MCP_VERSION = '0.11.0'",
                "const ENGINE_AGENT_MCP_VERSION = '0.12.0'",
            )
        ):
            die("Engine node-intelligence gateway MCP version is not registered")
        validate_engine_node_intelligence_image_archive(
            payload_dir / ENGINE_NODE_INTELLIGENCE_IMAGE_ARCHIVE_REL,
            descriptor,
        )
    else:
        expected_service_files = {"README.md", "activation.json"}
        actual_service_files = {
            child.relative_to(service_root).as_posix()
            for child in service_root.rglob("*")
            if child.is_file()
        }
        if actual_service_files != expected_service_files:
            die("Engine node-intelligence rollback payload file set mismatch")
        if sha256_file(gateway) != ENGINE_NODE_INTELLIGENCE_PREDECESSOR_GATEWAY_SHA256:
            die("Engine node-intelligence rollback gateway baseline mismatch")
    return descriptor


def is_engine_mcp_control_plane_slice(component, entries):
    return (
        component == "engine"
        and entries is not None
        and tuple(entries) == ENGINE_MCP_CONTROL_PLANE_ARTIFACT_ENTRIES
    )


def validate_engine_mcp_control_plane_payload(payload_dir, entries):
    if tuple(entries) != ENGINE_MCP_CONTROL_PLANE_ARTIFACT_ENTRIES:
        die("Engine MCP control-plane files.txt exact set/order mismatch")
    for rel, expected_sha256 in ENGINE_MCP_CONTROL_PLANE_TARGET_SHA256.items():
        path = payload_dir / rel
        if path.is_symlink() or not path.is_file() or sha256_file(path) != expected_sha256:
            die(f"Engine MCP control-plane target sha256 mismatch: {rel}")

    gateway = (payload_dir / ENGINE_NODE_INTELLIGENCE_GATEWAY_REL).read_text(encoding="utf-8")
    graph_route = (payload_dir / "nodedc-source/server/routes/ndcAgentMcp.js").read_text(
        encoding="utf-8"
    )
    installer = (
        payload_dir
        / "nodedc-source/server/assets/engine-agent-npm/bin/nodedc-engine-codex-agent.mjs"
    ).read_text(encoding="utf-8")
    package = read_strict_json(
        payload_dir / "nodedc-source/server/assets/engine-agent-npm/package.json",
        "Engine MCP Codex installer package",
    )
    if package.get("name") != "@nodedc/engine-codex-agent" or package.get("version") != "0.1.4":
        die("Engine MCP Codex installer package identity mismatch")
    if any(
        marker not in gateway
        for marker in (
            "const ENGINE_AGENT_MCP_VERSION = '0.5.0'",
            "engine_open_l2_change_session",
            "engine_get_l2_change_session",
            "engine_close_l2_change_session",
            "never_infer_expiry",
            "three_identical_failures_without_new_evidence",
            "engine_plan_data_product_read_grant",
            "engine_apply_data_product_read_grant",
            "engine_accept_data_product_read_grant",
            "engine_rollback_data_product_read_grant",
        )
    ):
        die("Engine MCP bounded-change-session contract is incomplete")
    if any(
        marker not in graph_route
        for marker in (
            "update_node_no_effect",
            "subworkflow_post_write_equality_failed",
            "verifiedWrite: true",
            "graphDigest: expectedDigest",
        )
    ):
        die("Engine MCP graph post-write equality contract is incomplete")
    if any(
        marker not in installer
        for marker in (
            "Do not interrupt the user after ordinary recoverable errors",
            "Never infer that a provider or managed capability token expired",
            "Three identical failures with no new evidence",
            "engine_plan_data_product_*_grant",
            "durable until an explicit rollback or revoke",
        )
    ):
        die("Engine MCP Codex bounded-autonomy policy is incomplete")
    combined = "\n".join((gateway, graph_route, installer)).lower()
    if "gelios" in combined or "robot2b" in combined:
        die("provider identity is forbidden in Engine MCP control-plane source")

    archive_path = payload_dir / "nodedc-source/server/assets/nodedc-engine-codex-agent-0.1.4.tgz"
    expected_members = {
        "package/bin/nodedc-engine-codex-agent.mjs": (
            payload_dir
            / "nodedc-source/server/assets/engine-agent-npm/bin/nodedc-engine-codex-agent.mjs"
        ).read_bytes(),
        "package/package.json": (
            payload_dir / "nodedc-source/server/assets/engine-agent-npm/package.json"
        ).read_bytes(),
    }
    observed_members = {}
    try:
        with tarfile.open(archive_path, "r:gz") as archive:
            for member in archive:
                if not (member.isfile() or member.isdir()) or member.name.startswith("/"):
                    die("Engine MCP Codex installer archive member is unsafe")
                if member.isfile():
                    source = archive.extractfile(member)
                    if source is None:
                        die("Engine MCP Codex installer archive member is unreadable")
                    observed_members[member.name] = source.read(MAX_FILE_BYTES + 1)
    except (OSError, tarfile.TarError):
        die("Engine MCP Codex installer archive is invalid")
    if observed_members != expected_members:
        die("Engine MCP Codex installer archive/source equality mismatch")

    n8n_route = (payload_dir / "nodedc-source/server/routes/n8n.js").read_text(
        encoding="utf-8"
    )
    if "engineDataProductReadGrantN8nAdapter" not in n8n_route:
        die("Engine MCP managed reader native adapter is missing")
    if "ndcDataProductReaderApi" not in n8n_route or "ndc_edprb_" not in n8n_route:
        die("Engine MCP managed reader credential contract is incomplete")
    if "read_grant_must_be_durable" not in n8n_route:
        die("Engine MCP managed reader durable lifecycle is missing")
    reader_service = (
        payload_dir / "nodedc-source/server/dataProductReadGrant/service.js"
    ).read_text(encoding="utf-8")
    if (
        "readerGrantLifetime: 'explicit-revoke'" not in reader_service
        or "expiresAt: null" not in reader_service
        or "ENGINE_READ_GRANT_TTL_DAYS" in reader_service
    ):
        die("Engine MCP managed reader explicit-revoke lifecycle is incomplete")
    publish_service = (
        payload_dir / "nodedc-source/server/dataProductPublishGrant/service.js"
    ).read_text(encoding="utf-8")
    if (
        "writerGrantLifetime: 'explicit-revoke'" not in publish_service
        or "migrateCurrentGrantToDurable" not in publish_service
        or "expiresAt: null" not in publish_service
        or "ENGINE_PUBLISH_GRANT_TTL_DAYS" in publish_service
    ):
        die("Engine MCP managed writer explicit-revoke lifecycle is incomplete")
    reader_override = payload_dir / ENGINE_DATA_PRODUCT_READ_GRANT_OVERRIDE_REL
    try:
        reader_override_text = reader_override.read_text(encoding="utf-8")
    except (OSError, UnicodeDecodeError):
        die("Engine MCP managed reader runtime override is unreadable")
    if reader_override_text != expected_engine_data_product_read_grant_override():
        die("Engine MCP managed reader runtime override mismatch")
    agent_store = (payload_dir / "nodedc-source/server/engineAgents/store.js").read_text(
        encoding="utf-8"
    )
    for scope in (
        "'engine:l2:data-product-read-grant:plan'",
        "'engine:l2:data-product-read-grant:write'",
    ):
        if scope not in agent_store:
            die(f"Engine MCP managed reader scope is missing: {scope}")

    descriptor = read_engine_node_intelligence_descriptor(
        payload_dir / ENGINE_MCP_CONTROL_PLANE_DESCRIPTOR_REL,
        "Engine MCP control-plane node-intelligence descriptor",
    )
    if (
        descriptor.get("action") != "activate"
        or descriptor["source"].get("gatewaySha256")
        != ENGINE_MCP_CONTROL_PLANE_TARGET_SHA256[ENGINE_NODE_INTELLIGENCE_GATEWAY_REL]
        or descriptor["source"].get("upstreamProjectionSha256")
        != ENGINE_MCP_CONTROL_PLANE_TARGET_SHA256[
            "nodedc-source/server/nodeIntelligence/upstreamProjection.js"
        ]
    ):
        die("Engine MCP control-plane descriptor target mismatch")
    return descriptor


def preflight_engine_mcp_control_plane_predecessor(payload_dir):
    candidate = validate_engine_mcp_control_plane_payload(
        payload_dir,
        ENGINE_MCP_CONTROL_PLANE_ARTIFACT_ENTRIES,
    )
    installed = current_engine_node_intelligence_descriptor()
    validate_installed_engine_node_intelligence_source(installed)
    if installed is None or installed.get("action") != "activate":
        die("Engine MCP control-plane requires active node intelligence")
    expected_candidate = json.loads(json.dumps(installed))
    expected_candidate["source"]["gatewaySha256"] = (
        ENGINE_MCP_CONTROL_PLANE_TARGET_SHA256[ENGINE_NODE_INTELLIGENCE_GATEWAY_REL]
    )
    expected_candidate["source"]["upstreamProjectionSha256"] = (
        ENGINE_MCP_CONTROL_PLANE_TARGET_SHA256[
            "nodedc-source/server/nodeIntelligence/upstreamProjection.js"
        ]
    )
    if candidate != expected_candidate:
        die("Engine MCP control-plane descriptor crosses node-intelligence source boundary")
    root = component_root("engine")
    for rel, expected_sha256 in ENGINE_MCP_CONTROL_PLANE_PREDECESSOR_SHA256.items():
        path = root / rel
        if path.is_symlink() or not path.is_file() or sha256_file(path) != expected_sha256:
            die(f"Engine MCP control-plane predecessor drift detected: {rel}")
    for rel in ENGINE_MCP_CONTROL_PLANE_NEW_PATHS:
        path = root / rel
        if path.exists() or path.is_symlink():
            die(f"Engine MCP control-plane new path already exists: {rel}")
    backend = preflight_engine_credential_backend_runtime()
    if backend["mode"] != "verified-derived-retry":
        die("Engine MCP control-plane requires the active immutable backend runtime")
    return {
        "descriptor": candidate,
        "predecessor_gateway_sha256": installed["source"]["gatewaySha256"],
        "target_gateway_sha256": candidate["source"]["gatewaySha256"],
        "backend_mode": backend["mode"],
    }


def accept_engine_mcp_control_plane_runtime():
    root = component_root("engine")
    descriptor = validate_engine_mcp_control_plane_payload(
        root,
        ENGINE_MCP_CONTROL_PLANE_ARTIFACT_ENTRIES,
    )
    installed = current_engine_node_intelligence_descriptor()
    if installed != descriptor:
        die("Engine MCP control-plane installed descriptor equality failed")
    validate_installed_engine_node_intelligence_source(installed)
    backend = preflight_engine_credential_backend_runtime()
    if backend["mode"] != "verified-derived-retry":
        die("Engine MCP control-plane backend runtime acceptance failed")
    live = run_engine_backend_probe(
        (
            "node",
            "--input-type=module",
            "-e",
            """
const module=await import('file:///app/server/routes/engineAgentGateway.js');
const store=await import('file:///app/server/engineAgents/store.js');
const names=new Set(module.engineAgentTools.map((tool)=>tool.name));
const required=['engine_plan_data_product_read_grant','engine_apply_data_product_read_grant','engine_accept_data_product_read_grant','engine_rollback_data_product_read_grant'];
const scopes=['engine:l2:data-product-read-grant:plan','engine:l2:data-product-read-grant:write'];
if(!required.every((name)=>names.has(name))||!scopes.every((scope)=>store.ENGINE_AGENT_SCOPES.includes(scope)))process.exit(2);
process.stdout.write('engine-mcp-reader-grant:0.5.0:'+required.length+':'+scopes.length);
""".strip(),
        ),
        "Engine MCP managed reader capability",
        container_id=engine_backend_container_id(),
    )
    if live != "engine-mcp-reader-grant:0.5.0:4:2":
        die("Engine MCP managed reader live capability acceptance mismatch")
    return {
        "gateway_sha256": descriptor["source"]["gatewaySha256"],
        "backend_mode": backend["mode"],
        "reader_grant": live,
    }


def is_engine_mcp_ontology_sdk_slice(component, entries):
    return (
        component == "engine"
        and entries is not None
        and tuple(entries) == ENGINE_MCP_ONTOLOGY_SDK_ARTIFACT_ENTRIES
    )


def validate_engine_mcp_ontology_sdk_payload(payload_dir, entries):
    if tuple(entries) != ENGINE_MCP_ONTOLOGY_SDK_ARTIFACT_ENTRIES:
        die("Engine MCP Ontology/SDK files.txt exact set/order mismatch")
    for rel, expected_sha256 in ENGINE_MCP_ONTOLOGY_SDK_TARGET_SHA256.items():
        path = payload_dir / rel
        if path.is_symlink() or not path.is_file() or sha256_file(path) != expected_sha256:
            die(f"Engine MCP Ontology/SDK target sha256 mismatch: {rel}")

    gateway = (payload_dir / ENGINE_NODE_INTELLIGENCE_GATEWAY_REL).read_text(
        encoding="utf-8"
    )
    installer_path = (
        payload_dir
        / "nodedc-source/server/assets/engine-agent-npm/bin/nodedc-engine-codex-agent.mjs"
    )
    installer = installer_path.read_text(encoding="utf-8")
    package_path = payload_dir / "nodedc-source/server/assets/engine-agent-npm/package.json"
    package = read_strict_json(package_path, "Engine MCP Codex installer package")
    if package.get("name") != "@nodedc/engine-codex-agent" or package.get("version") != "0.1.5":
        die("Engine MCP Ontology/SDK installer package identity mismatch")
    if any(
        marker not in gateway
        for marker in (
            "const ENGINE_AGENT_MCP_VERSION = '0.6.0'",
            "authenticateEngineAgentOntologyToken",
            "apiRouter.post('/ontology-mcp'",
            "process.env.NODEDC_INTERNAL_ACCESS_TOKEN",
            "serverName: 'nodedc-engine-agent'",
            "serverName: 'nodedc_ontology'",
        )
    ):
        die("Engine MCP separate Ontology gateway contract is incomplete")
    if any(
        marker not in installer
        for marker in (
            "const ENGINE_SERVER_NAME = 'nodedc-engine-agent'",
            "const ONTOLOGY_SERVER_NAME = 'nodedc_ontology'",
            "Ontology tools/catalog are never embedded or multiplexed into Engine MCP",
            "version: '0.1.5'",
        )
    ):
        die("Engine MCP separate Ontology installer contract is incomplete")

    archive_path = payload_dir / "nodedc-source/server/assets/nodedc-engine-codex-agent-0.1.5.tgz"
    expected_members = {
        "package/bin/nodedc-engine-codex-agent.mjs": installer_path.read_bytes(),
        "package/package.json": package_path.read_bytes(),
    }
    observed_members = {}
    try:
        with tarfile.open(archive_path, "r:gz") as archive:
            for member in archive:
                if not (member.isfile() or member.isdir()) or member.name.startswith("/"):
                    die("Engine MCP Ontology/SDK installer archive member is unsafe")
                if member.isfile():
                    source = archive.extractfile(member)
                    if source is None:
                        die("Engine MCP Ontology/SDK installer archive member is unreadable")
                    observed_members[member.name] = source.read(MAX_FILE_BYTES + 1)
    except (OSError, tarfile.TarError):
        die("Engine MCP Ontology/SDK installer archive is invalid")
    if observed_members != expected_members:
        die("Engine MCP Ontology/SDK installer archive/source equality mismatch")

    catalog = read_strict_json(
        payload_dir / "nodedc-source/server/assets/provider-packages/v1/catalog.json",
        "Engine provider security catalog",
    )
    packages = catalog.get("packages") if isinstance(catalog, dict) else None
    if not isinstance(packages, list) or len(packages) != 1:
        die("Engine provider security catalog must contain one active package")
    provider = packages[0]
    capabilities = provider.get("capabilities") if isinstance(provider, dict) else None
    capability = capabilities[0] if isinstance(capabilities, list) and len(capabilities) == 1 else None
    request = capability.get("request") if isinstance(capability, dict) else None
    if (
        provider.get("id") != "gelios.provider.v2"
        or provider.get("version") != "2.0.0"
        or (provider.get("providerCredential") or {}).get("credentialType") != "httpQueryAuth"
        or not isinstance(request, dict)
        or request.get("method") != "GET"
        or request.get("url") != "https://admin.geliospro.com/sdk/?svc=get_units&params=%7B%7D"
    ):
        die("Engine Gelios SDK/query-auth security projection mismatch")
    resolver = (
        payload_dir / "nodedc-source/server/dataProductPublishGrant/providerCatalog.js"
    ).read_text(encoding="utf-8")
    if "new Set(['httpBearerAuth', 'httpQueryAuth'])" not in resolver:
        die("Engine provider credential type allowlist mismatch")
    store = (payload_dir / "nodedc-source/server/engineAgents/store.js").read_text(
        encoding="utf-8"
    )
    if any(
        marker not in store
        for marker in (
            "const STORE_VERSION = 3",
            "ontologyTokenHash",
            "`ndc_eao_${",
            "authenticateEngineAgentOntologyToken",
        )
    ):
        die("Engine separate Ontology token store migration is incomplete")

    descriptor = read_engine_node_intelligence_descriptor(
        payload_dir / ENGINE_MCP_CONTROL_PLANE_DESCRIPTOR_REL,
        "Engine MCP Ontology/SDK node-intelligence descriptor",
    )
    if (
        descriptor.get("action") != "activate"
        or descriptor["source"].get("gatewaySha256")
        != ENGINE_MCP_ONTOLOGY_SDK_TARGET_SHA256[ENGINE_NODE_INTELLIGENCE_GATEWAY_REL]
        or descriptor["source"].get("upstreamProjectionSha256")
        != ENGINE_MCP_CONTROL_PLANE_TARGET_SHA256[
            "nodedc-source/server/nodeIntelligence/upstreamProjection.js"
        ]
    ):
        die("Engine MCP Ontology/SDK descriptor target mismatch")
    return descriptor


def preflight_engine_mcp_ontology_sdk_predecessor(payload_dir):
    candidate = validate_engine_mcp_ontology_sdk_payload(
        payload_dir,
        ENGINE_MCP_ONTOLOGY_SDK_ARTIFACT_ENTRIES,
    )
    installed = current_engine_node_intelligence_descriptor()
    validate_installed_engine_node_intelligence_source(installed)
    if installed is None or installed.get("action") != "activate":
        die("Engine MCP Ontology/SDK requires active node intelligence")
    expected_candidate = json.loads(json.dumps(installed))
    expected_candidate["source"]["gatewaySha256"] = (
        ENGINE_MCP_ONTOLOGY_SDK_TARGET_SHA256[ENGINE_NODE_INTELLIGENCE_GATEWAY_REL]
    )
    if candidate != expected_candidate:
        die("Engine MCP Ontology/SDK descriptor crosses node-intelligence source boundary")
    root = component_root("engine")
    for rel, expected_sha256 in ENGINE_MCP_ONTOLOGY_SDK_PREDECESSOR_SHA256.items():
        path = root / rel
        if path.is_symlink() or not path.is_file() or sha256_file(path) != expected_sha256:
            die(f"Engine MCP Ontology/SDK predecessor drift detected: {rel}")
    for rel in ENGINE_MCP_ONTOLOGY_SDK_NEW_PATHS:
        path = root / rel
        if path.exists() or path.is_symlink():
            die(f"Engine MCP Ontology/SDK new path already exists: {rel}")
    backend = preflight_engine_credential_backend_runtime()
    if backend["mode"] != "verified-derived-retry":
        die("Engine MCP Ontology/SDK requires the active immutable backend runtime")
    return {
        "descriptor": candidate,
        "predecessor_gateway_sha256": installed["source"]["gatewaySha256"],
        "target_gateway_sha256": candidate["source"]["gatewaySha256"],
        "backend_mode": backend["mode"],
    }


def accept_engine_mcp_ontology_sdk_runtime():
    root = component_root("engine")
    descriptor = validate_engine_mcp_ontology_sdk_payload(
        root,
        ENGINE_MCP_ONTOLOGY_SDK_ARTIFACT_ENTRIES,
    )
    installed = current_engine_node_intelligence_descriptor()
    if installed != descriptor:
        die("Engine MCP Ontology/SDK installed descriptor equality failed")
    validate_installed_engine_node_intelligence_source(installed)
    backend = preflight_engine_credential_backend_runtime()
    if backend["mode"] != "verified-derived-retry":
        die("Engine MCP Ontology/SDK backend runtime acceptance failed")
    live = run_engine_backend_probe(
        (
            "node",
            "--input-type=module",
            "-e",
            """
const gateway=await import('file:///app/server/routes/engineAgentGateway.js');
const store=await import('file:///app/server/engineAgents/store.js');
const catalog=JSON.parse(await (await import('node:fs/promises')).readFile('/app/server/assets/provider-packages/v1/catalog.json','utf8'));
const provider=catalog.packages?.[0];
if(gateway.ENGINE_AGENT_MCP_VERSION!=='0.6.0')process.exit(2);
if(typeof store.authenticateEngineAgentOntologyToken!=='function')process.exit(3);
if(provider?.id!=='gelios.provider.v2'||provider?.providerCredential?.credentialType!=='httpQueryAuth')process.exit(4);
process.stdout.write('engine-mcp-ontology-sdk:0.6.0:0.1.5:gelios.provider.v2:httpQueryAuth');
""".strip(),
        ),
        "Engine MCP Ontology/SDK capability",
        container_id=engine_backend_container_id(),
    )
    expected = "engine-mcp-ontology-sdk:0.6.0:0.1.5:gelios.provider.v2:httpQueryAuth"
    if live != expected:
        die("Engine MCP Ontology/SDK live capability acceptance mismatch")
    return {
        "gateway_sha256": descriptor["source"]["gatewaySha256"],
        "backend_mode": backend["mode"],
        "capability": live,
    }


def is_engine_mcp_autonomy_provider_v5_slice(component, entries):
    return (
        component == "engine"
        and entries is not None
        and tuple(entries) == ENGINE_MCP_AUTONOMY_PROVIDER_V5_ARTIFACT_ENTRIES
    )


def validate_engine_mcp_autonomy_provider_v5_payload(payload_dir, entries):
    if tuple(entries) != ENGINE_MCP_AUTONOMY_PROVIDER_V5_ARTIFACT_ENTRIES:
        die("Engine MCP autonomy/provider v5 files.txt exact set/order mismatch")
    for rel, expected_sha256 in ENGINE_MCP_AUTONOMY_PROVIDER_V5_TARGET_SHA256.items():
        path = payload_dir / rel
        if path.is_symlink() or not path.is_file() or sha256_file(path) != expected_sha256:
            die(f"Engine MCP autonomy/provider v5 target sha256 mismatch: {rel}")

    gateway = (payload_dir / ENGINE_NODE_INTELLIGENCE_GATEWAY_REL).read_text(
        encoding="utf-8"
    )
    installer_path = (
        payload_dir
        / "nodedc-source/server/assets/engine-agent-npm/bin/nodedc-engine-codex-agent.mjs"
    )
    installer = installer_path.read_text(encoding="utf-8")
    package_path = payload_dir / "nodedc-source/server/assets/engine-agent-npm/package.json"
    package = read_strict_json(package_path, "Engine MCP Codex installer package")
    if package.get("name") != "@nodedc/engine-codex-agent" or package.get("version") != "0.1.6":
        die("Engine MCP autonomy/provider v5 installer package identity mismatch")
    if any(
        marker not in gateway
        for marker in (
            "const ENGINE_AGENT_MCP_VERSION = '0.6.0'",
            "authenticateEngineAgentOntologyToken",
            "apiRouter.post('/ontology-mcp'",
            "'nodedc-engine-codex-agent-0.1.6.tgz'",
        )
    ):
        die("Engine MCP autonomy/provider v5 gateway contract is incomplete")
    if any(
        marker not in installer
        for marker in (
            "MCP tool availability establishes capability authority",
            "the user's requested objective establishes intent scope",
            "machine safety barrier, not a permission ceremony",
            "Never repeat an identical read, validation, apply or run",
            "Three identical failures with no new evidence or state change are a critical stop",
            "const ONTOLOGY_SERVER_NAME = 'nodedc_ontology'",
            "version: '0.1.6'",
        )
    ) or "only with explicit user confirmation" in installer:
        die("Engine MCP capability-scoped autonomy policy is incomplete")

    archive_path = payload_dir / "nodedc-source/server/assets/nodedc-engine-codex-agent-0.1.6.tgz"
    expected_members = {
        "package/bin/nodedc-engine-codex-agent.mjs": installer_path.read_bytes(),
        "package/package.json": package_path.read_bytes(),
    }
    observed_members = {}
    try:
        with tarfile.open(archive_path, "r:gz") as archive:
            for member in archive:
                if not (member.isfile() or member.isdir()) or member.name.startswith("/"):
                    die("Engine MCP autonomy/provider v5 installer archive member is unsafe")
                if member.isfile():
                    source = archive.extractfile(member)
                    if source is None:
                        die("Engine MCP autonomy/provider v5 installer archive member is unreadable")
                    observed_members[member.name] = source.read(MAX_FILE_BYTES + 1)
    except (OSError, tarfile.TarError):
        die("Engine MCP autonomy/provider v5 installer archive is invalid")
    if observed_members != expected_members:
        die("Engine MCP autonomy/provider v5 installer archive/source equality mismatch")

    catalog = read_strict_json(
        payload_dir / "nodedc-source/server/assets/provider-packages/v1/catalog.json",
        "Engine provider security catalog",
    )
    packages = catalog.get("packages") if isinstance(catalog, dict) else None
    if (
        catalog.get("schemaVersion") != "nodedc.engine.provider-security-catalog/v1"
        or not isinstance(packages, list)
        or [item.get("id") for item in packages if isinstance(item, dict)]
        != ["gelios.provider.v4", "gelios.provider.v5"]
    ):
        die("Engine Gelios provider v4/v5 catalog identity mismatch")
    expected_products = {
        "gelios.provider.v4": "fleet.positions.current.v3",
        "gelios.provider.v5": "fleet.positions.current.v4",
    }
    expected_requests = [
        ("gelios.monitoring_config.current.read", "https://api.geliospro.com/api/v1/users/me/monitoring-config"),
        ("gelios.units.current.read", "https://api.geliospro.com/api/v1/units?incltrip=true"),
    ]
    for provider in packages:
        provider_id = provider.get("id")
        credential = provider.get("providerCredential") or {}
        capabilities = provider.get("capabilities")
        observed_requests = [
            (item.get("id"), (item.get("request") or {}).get("url"))
            for item in capabilities
        ] if isinstance(capabilities, list) else None
        if (
            provider_id not in expected_products
            or credential.get("credentialType") != "ndcProviderRotatingAccessApi"
            or credential.get("authModeId") != "gelios.rest-rotating-bearer.v3"
            or observed_requests != expected_requests
            or any(item.get("dataProductIds") != [expected_products[provider_id]] for item in capabilities)
        ):
            die("Engine Gelios provider v4/v5 security projection mismatch")

    store = (payload_dir / "nodedc-source/server/engineAgents/store.js").read_text(
        encoding="utf-8"
    )
    if any(
        marker not in store
        for marker in (
            "const STORE_VERSION = 3",
            "ontologyTokenHash",
            "authenticateEngineAgentOntologyToken",
        )
    ):
        die("Engine MCP autonomy/provider v5 Ontology token store migration is incomplete")

    descriptor = read_engine_node_intelligence_descriptor(
        payload_dir / ENGINE_MCP_CONTROL_PLANE_DESCRIPTOR_REL,
        "Engine MCP autonomy/provider v5 node-intelligence descriptor",
    )
    if (
        descriptor.get("action") != "activate"
        or descriptor["source"].get("gatewaySha256")
        != ENGINE_MCP_AUTONOMY_PROVIDER_V5_TARGET_SHA256[ENGINE_NODE_INTELLIGENCE_GATEWAY_REL]
        or descriptor["source"].get("upstreamProjectionSha256")
        != ENGINE_MCP_CONTROL_PLANE_TARGET_SHA256[
            "nodedc-source/server/nodeIntelligence/upstreamProjection.js"
        ]
    ):
        die("Engine MCP autonomy/provider v5 descriptor target mismatch")
    return descriptor


def preflight_engine_mcp_autonomy_provider_v5_predecessor(payload_dir):
    candidate = validate_engine_mcp_autonomy_provider_v5_payload(
        payload_dir,
        ENGINE_MCP_AUTONOMY_PROVIDER_V5_ARTIFACT_ENTRIES,
    )
    installed = current_engine_node_intelligence_descriptor()
    validate_installed_engine_node_intelligence_source(installed)
    if installed is None or installed.get("action") != "activate":
        die("Engine MCP autonomy/provider v5 requires active node intelligence")
    expected_candidate = json.loads(json.dumps(installed))
    expected_candidate["source"]["gatewaySha256"] = (
        ENGINE_MCP_AUTONOMY_PROVIDER_V5_TARGET_SHA256[ENGINE_NODE_INTELLIGENCE_GATEWAY_REL]
    )
    if candidate != expected_candidate:
        die("Engine MCP autonomy/provider v5 crosses node-intelligence source boundary")
    root = component_root("engine")
    for rel, expected_sha256 in ENGINE_MCP_AUTONOMY_PROVIDER_V5_PREDECESSOR_SHA256.items():
        path = root / rel
        if path.is_symlink() or not path.is_file() or sha256_file(path) != expected_sha256:
            die(f"Engine MCP autonomy/provider v5 predecessor drift detected: {rel}")
    for rel in ENGINE_MCP_AUTONOMY_PROVIDER_V5_NEW_PATHS:
        path = root / rel
        if path.exists() or path.is_symlink():
            die(f"Engine MCP autonomy/provider v5 new path already exists: {rel}")
    backend = preflight_engine_credential_backend_runtime()
    if backend["mode"] != "verified-derived-retry":
        die("Engine MCP autonomy/provider v5 requires the active immutable backend runtime")
    return {
        "descriptor": candidate,
        "predecessor_gateway_sha256": installed["source"]["gatewaySha256"],
        "target_gateway_sha256": candidate["source"]["gatewaySha256"],
        "backend_mode": backend["mode"],
    }


def engine_mcp_autonomy_provider_v5_installed_state():
    root = component_root("engine")
    target = all(
        (root / rel).is_file() and not (root / rel).is_symlink()
        and sha256_file(root / rel) == expected
        for rel, expected in ENGINE_MCP_AUTONOMY_PROVIDER_V5_TARGET_SHA256.items()
    )
    descriptor = current_engine_node_intelligence_descriptor()
    if descriptor is not None:
        validate_installed_engine_node_intelligence_source(descriptor)
    if target and descriptor and descriptor.get("source", {}).get("gatewaySha256") == (
        ENGINE_MCP_AUTONOMY_PROVIDER_V5_TARGET_SHA256[ENGINE_NODE_INTELLIGENCE_GATEWAY_REL]
    ):
        return "target"
    predecessor = all(
        (root / rel).is_file() and not (root / rel).is_symlink()
        and sha256_file(root / rel) == expected
        for rel, expected in ENGINE_MCP_AUTONOMY_PROVIDER_V5_PREDECESSOR_SHA256.items()
    )
    new_paths_absent = all(
        not (root / rel).exists() and not (root / rel).is_symlink()
        for rel in ENGINE_MCP_AUTONOMY_PROVIDER_V5_NEW_PATHS
    )
    if predecessor and new_paths_absent and descriptor and descriptor.get("source", {}).get("gatewaySha256") == (
        ENGINE_MCP_AUTONOMY_PROVIDER_V5_PREDECESSOR_SHA256[ENGINE_NODE_INTELLIGENCE_GATEWAY_REL]
    ):
        return "predecessor"
    die("Engine MCP autonomy/provider v5 installed state is neither target nor rollback predecessor")


def accept_engine_mcp_autonomy_provider_v5_runtime():
    root = component_root("engine")
    descriptor = validate_engine_mcp_autonomy_provider_v5_payload(
        root,
        ENGINE_MCP_AUTONOMY_PROVIDER_V5_ARTIFACT_ENTRIES,
    )
    installed = current_engine_node_intelligence_descriptor()
    if installed != descriptor:
        die("Engine MCP autonomy/provider v5 installed descriptor equality failed")
    validate_installed_engine_node_intelligence_source(installed)
    backend = preflight_engine_credential_backend_runtime()
    if backend["mode"] != "verified-derived-retry":
        die("Engine MCP autonomy/provider v5 backend runtime acceptance failed")
    live = run_engine_backend_probe(
        (
            "node",
            "--input-type=module",
            "-e",
            """
const gateway=await import('file:///app/server/routes/engineAgentGateway.js');
const store=await import('file:///app/server/engineAgents/store.js');
const fs=await import('node:fs/promises');
const catalog=JSON.parse(await fs.readFile('/app/server/assets/provider-packages/v1/catalog.json','utf8'));
const pkg=JSON.parse(await fs.readFile('/app/server/assets/engine-agent-npm/package.json','utf8'));
const ids=catalog.packages?.map((item)=>item.id).join(',');
const target=catalog.packages?.find((item)=>item.id==='gelios.provider.v5');
if(gateway.ENGINE_AGENT_MCP_VERSION!=='0.6.0')process.exit(2);
if(typeof store.authenticateEngineAgentOntologyToken!=='function')process.exit(3);
if(pkg.version!=='0.1.6'||ids!=='gelios.provider.v4,gelios.provider.v5')process.exit(4);
if(target?.capabilities?.some((item)=>item.dataProductIds?.[0]!=='fleet.positions.current.v4'))process.exit(5);
process.stdout.write('engine-mcp-autonomy-provider-v5:0.6.0:0.1.6:'+ids);
""".strip(),
        ),
        "Engine MCP autonomy/provider v5 capability",
        container_id=engine_backend_container_id(),
    )
    expected = "engine-mcp-autonomy-provider-v5:0.6.0:0.1.6:gelios.provider.v4,gelios.provider.v5"
    if live != expected:
        die("Engine MCP autonomy/provider v5 live capability acceptance mismatch")
    return {
        "gateway_sha256": descriptor["source"]["gatewaySha256"],
        "backend_mode": backend["mode"],
        "capability": live,
    }


def is_engine_provider_security_catalog_slice(component, entries):
    return (
        component == "engine"
        and entries is not None
        and tuple(entries) == ENGINE_PROVIDER_SECURITY_CATALOG_ARTIFACT_ENTRIES
    )


def validate_engine_provider_security_catalog_payload(payload_dir, entries):
    if tuple(entries) != ENGINE_PROVIDER_SECURITY_CATALOG_ARTIFACT_ENTRIES:
        die("Engine provider security catalog files.txt exact set/order mismatch")
    catalog_path = payload_dir / ENGINE_PROVIDER_SECURITY_CATALOG_REL
    if (
        catalog_path.is_symlink()
        or not catalog_path.is_file()
        or sha256_file(catalog_path) != ENGINE_PROVIDER_SECURITY_CATALOG_TARGET_SHA256
    ):
        die("Engine provider security catalog target sha256 mismatch")
    catalog = read_strict_json(catalog_path, "Engine provider security catalog")
    packages = catalog.get("packages") if isinstance(catalog, dict) else None
    package_ids = [item.get("id") for item in packages if isinstance(item, dict)] \
        if isinstance(packages, list) else None
    provider = next(
        (
            item for item in packages
            if isinstance(item, dict) and item.get("id") == "gelios.provider.v8"
        ),
        None,
    ) if isinstance(packages, list) else None
    previous_provider = next(
        (
            item for item in packages
            if isinstance(item, dict) and item.get("id") == "gelios.provider.v7"
        ),
        None,
    ) if isinstance(packages, list) else None
    capabilities = provider.get("capabilities") if isinstance(provider, dict) else None
    capability = capabilities[0] if isinstance(capabilities, list) and len(capabilities) == 1 else None
    request = capability.get("request") if isinstance(capability, dict) else None
    credential = provider.get("providerCredential") if isinstance(provider, dict) else None
    publisher = provider.get("publisher") if isinstance(provider, dict) else None
    if (
        catalog.get("schemaVersion") != "nodedc.engine.provider-security-catalog/v1"
        or package_ids != [
            "gelios.provider.v1",
            "gelios.provider.v4",
            "gelios.provider.v5",
            "moscow-department-of-transport.pmd-slow-zones.v1",
            "gelios.provider.v7",
            "gelios.provider.v8",
        ]
        or not isinstance(provider, dict)
        or provider.get("version") != "8.0.0"
        or provider.get("providerId") != "gelios"
        or credential != {
            "authModeId": "gelios.rest-rotating-bearer.v3",
            "credentialType": "ndcProviderRotatingAccessApi",
        }
        or not isinstance(capability, dict)
        or capability.get("id") != "gelios.units.current.read"
        or capability.get("classification") != "read"
        or capability.get("status") != "implemented"
        or request != {
            "method": "GET",
            "url": (
                "https://api.geliospro.com/api/v1/units?incltrip=true&inclcntrs=true"
                "&inclsnsrs=true&incllsv=true"
            ),
        }
        or capability.get("dataProductIds") != ["fleet.units.profile.current.v1"]
        or publisher != {
            "nodeType": "n8n-nodes-ndc.ndcDataProductPublish",
            "credentialType": "ndcDataProductWriterApi",
        }
        or previous_provider != {
            "id": "gelios.provider.v7",
            "version": "7.0.0",
            "providerId": "gelios",
            "providerCredential": {
                "authModeId": "gelios.rest-rotating-bearer.v3",
                "credentialType": "ndcProviderRotatingAccessApi",
            },
            "capabilities": [
                {
                    "id": "gelios.units.current.read",
                    "classification": "read",
                    "status": "implemented",
                    "request": {
                        "method": "GET",
                        "url": (
                            "https://api.geliospro.com/api/v1/units?incltrip=true"
                            "&inclcntrs=true&inclsnsrs=true&incllsv=true"
                        ),
                    },
                    "dataProductIds": ["fleet.positions.current.v5"],
                },
            ],
            "publisher": {
                "nodeType": "n8n-nodes-ndc.ndcDataProductPublish",
                "credentialType": "ndcDataProductWriterApi",
            },
        }
    ):
        die("Engine provider security catalog v7/v8 projection mismatch")
    return catalog


def preflight_engine_provider_security_catalog_predecessor():
    catalog_path = component_root("engine") / ENGINE_PROVIDER_SECURITY_CATALOG_REL
    try:
        path_stat = catalog_path.lstat()
    except FileNotFoundError:
        die("Engine provider security catalog predecessor is missing")
    if stat.S_ISLNK(path_stat.st_mode) or not stat.S_ISREG(path_stat.st_mode):
        die("Engine provider security catalog predecessor is unsafe")
    actual_sha256 = sha256_file(catalog_path)
    if actual_sha256 != ENGINE_PROVIDER_SECURITY_CATALOG_PREDECESSOR_SHA256:
        die(
            "Engine provider security catalog predecessor drift detected: "
            f"expected={ENGINE_PROVIDER_SECURITY_CATALOG_PREDECESSOR_SHA256} "
            f"actual={actual_sha256}"
        )
    backend = preflight_engine_credential_backend_runtime()
    if backend["mode"] != "verified-derived-retry":
        die("Engine provider security catalog requires the active immutable backend")
    return {"catalog_sha256": actual_sha256, "backend_mode": backend["mode"]}


def accept_engine_provider_security_catalog_runtime():
    root = component_root("engine")
    validate_engine_provider_security_catalog_payload(
        root,
        ENGINE_PROVIDER_SECURITY_CATALOG_ARTIFACT_ENTRIES,
    )
    live = run_engine_backend_probe(
        (
            "node",
            "--input-type=module",
            "-e",
            """
const module=await import('file:///app/server/dataProductPublishGrant/providerCatalog.js');
const catalog=await module.loadProviderSecurityCatalog();
const validation=module.validateProviderSecurityCatalog(catalog);
const provider=catalog.packages?.find((item)=>item.id==='gelios.provider.v8');
const capability=provider?.capabilities?.[0];
const slot='ndcProviderRotatingAccessApi';
const credential={id:'native-provider',name:'provider',nodeDcCredentialId:'provider-ref'};
const policy={kind:'httpRequest',allowedHosts:['api.geliospro.com'],requireHttps:true,disableRedirects:true};
const queryParameters={parameters:[{name:'incltrip',value:'true'},{name:'inclcntrs',value:'true'},{name:'inclsnsrs',value:'true'},{name:'incllsv',value:'true'}]};
const source={id:'units',data:{n8n:{id:'units',name:'units',type:'n8n-nodes-base.httpRequest',parameters:{method:'GET',url:'https://api.geliospro.com/api/v1/units',sendQuery:true,specifyQuery:'keypair',queryParameters},credentials:{[slot]:credential}},nodedcAgentCredentialPolicies:{[slot]:policy}}};
const profilePublish={id:'profile-publish',data:{n8n:{id:'profile-publish',name:'profile-publish',type:'n8n-nodes-ndc.ndcDataProductPublish',parameters:{dataProductId:'fleet.units.profile.current.v1'},credentials:{}}}};
const positionsPublish={id:'positions-publish',data:{n8n:{id:'positions-publish',name:'positions-publish',type:'n8n-nodes-ndc.ndcDataProductPublish',parameters:{dataProductId:'fleet.positions.current.v5'},credentials:{}}}};
const profileGraph={nodes:[source,profilePublish],edges:[{source:'units',target:'profile-publish'}]};
const positionsGraph={nodes:[source,positionsPublish],edges:[{source:'units',target:'positions-publish'}]};
const profileResolved=module.resolveProviderConnectionFromGraph({graph:profileGraph,targetNodeId:'profile-publish',catalog});
const positionsResolved=module.resolveProviderConnectionFromGraph({graph:positionsGraph,targetNodeId:'positions-publish',catalog});
const drift=structuredClone(profileGraph);drift.nodes[0].data.n8n.parameters.queryParameters.parameters.pop();
const rejected=module.resolveProviderConnectionFromGraph({graph:drift,targetNodeId:'profile-publish',catalog});
if(!validation.ok||provider?.providerCredential?.credentialType!==slot||capability?.request?.url!=='https://api.geliospro.com/api/v1/units?incltrip=true&inclcntrs=true&inclsnsrs=true&incllsv=true'||capability?.dataProductIds?.[0]!=='fleet.units.profile.current.v1'||!profileResolved.ok||profileResolved.descriptor?.packageId!=='gelios.provider.v8'||profileResolved.descriptor?.providerCredentialRef!=='provider-ref'||!positionsResolved.ok||positionsResolved.descriptor?.packageId!=='gelios.provider.v7'||positionsResolved.descriptor?.dataProductId!=='fleet.positions.current.v5'||rejected.blockers?.join(',')!=='publish_grant_provider_request_not_exact')process.exit(2);
process.stdout.write('engine-provider-catalog:gelios.provider.v7:fleet.positions.current.v5|gelios.provider.v8:fleet.units.profile.current.v1');
""".strip(),
        ),
        "Engine provider security catalog v8 unit profile",
        container_id=engine_backend_container_id(),
    )
    expected = (
        "engine-provider-catalog:gelios.provider.v7:fleet.positions.current.v5|"
        "gelios.provider.v8:fleet.units.profile.current.v1"
    )
    if live != expected:
        die("Engine provider security catalog live acceptance mismatch")
    return {"catalog_sha256": ENGINE_PROVIDER_SECURITY_CATALOG_TARGET_SHA256, "live": live}


def accept_engine_composite_provider_runtime():
    catalog_path = component_root("engine") / ENGINE_PROVIDER_SECURITY_CATALOG_REL
    if (
        catalog_path.is_symlink()
        or not catalog_path.is_file()
        or sha256_file(catalog_path)
        != ENGINE_PUBLISH_GRANT_COMPOSITE_PROVIDER_CATALOG_TARGET_SHA256
    ):
        return None
    live = run_engine_backend_probe(
        (
            "node",
            "--input-type=module",
            "-e",
            """
const module=await import('file:///app/server/dataProductPublishGrant/providerCatalog.js');
const catalog=await module.loadProviderSecurityCatalog();
const validation=module.validateProviderSecurityCatalog(catalog);
const credential={id:'native-provider',name:'provider',nodeDcCredentialId:'provider-ref'};
const policy={kind:'httpRequest',allowedHosts:['api.geliospro.com'],requireHttps:true,disableRedirects:true};
const slot='ndcProviderRotatingAccessApi';
const read=(id,url,parameters={})=>({id,data:{n8n:{id,name:id,type:'n8n-nodes-base.httpRequest',parameters:{method:'GET',url,...parameters},credentials:{[slot]:credential}},nodedcAgentCredentialPolicies:{[slot]:policy}}});
const query={sendQuery:true,specifyQuery:'keypair',queryParameters:{parameters:[{name:'incltrip',value:'true'}]}};
const graph={nodes:[read('monitoring','https://api.geliospro.com/api/v1/users/me/monitoring-config'),read('units','https://api.geliospro.com/api/v1/units',query),{id:'publish',data:{n8n:{id:'publish',name:'publish',type:'n8n-nodes-ndc.ndcDataProductPublish',parameters:{dataProductId:'fleet.positions.current.v3'},credentials:{}}}}],edges:[{source:'monitoring',target:'publish'},{source:'units',target:'publish'}]};
const resolved=module.resolveProviderConnectionFromGraph({graph,targetNodeId:'publish',catalog});
if(!validation.ok||catalog.packages?.[0]?.id!=='gelios.provider.v4'||catalog.packages?.[0]?.providerCredential?.credentialType!==slot||!resolved.ok||resolved.descriptor?.providerCredentialRef!=='provider-ref'||resolved.descriptor?.capabilityIds?.join(',')!=='gelios.monitoring_config.current.read,gelios.units.current.read'||resolved.descriptor?.providerRequestNodeIds?.join(',')!=='monitoring,units')process.exit(2);
process.stdout.write('engine-composite-provider:gelios.provider.v4:ndcProviderRotatingAccessApi:fleet.positions.current.v3:monitoring,units');
""".strip(),
        ),
        "Engine composite provider authority",
        container_id=engine_backend_container_id(),
    )
    expected = (
        "engine-composite-provider:gelios.provider.v4:"
        "ndcProviderRotatingAccessApi:fleet.positions.current.v3:monitoring,units"
    )
    if live != expected:
        die("Engine composite provider live acceptance mismatch")
    return {
        "catalog_sha256": ENGINE_PUBLISH_GRANT_COMPOSITE_PROVIDER_CATALOG_TARGET_SHA256,
        "live": live,
    }


def accept_engine_provider_rotating_slot_runtime():
    root = component_root("engine")
    validate_engine_provider_rotating_slot_slice(
        root,
        ENGINE_PROVIDER_ROTATING_SLOT_ARTIFACT_ENTRIES,
    )
    live = run_engine_backend_probe(
        (
            "node",
            "--input-type=module",
            "-e",
            """
const module=await import('file:///app/server/dataProductPublishGrant/providerCatalog.js');
const catalog=await module.loadProviderSecurityCatalog();
const validation=module.validateProviderSecurityCatalog(catalog);
const credential={id:'native-provider',name:'provider',nodeDcCredentialId:'provider-ref'};
const policy={kind:'httpRequest',allowedHosts:['api.geliospro.com'],requireHttps:true,disableRedirects:true};
const slot='ndcProviderRotatingAccessApi';
const read=(id,url,parameters={})=>({id,data:{n8n:{id,name:id,type:'n8n-nodes-base.httpRequest',parameters:{method:'GET',url,...parameters},credentials:{[slot]:credential}},nodedcAgentCredentialPolicies:{[slot]:policy}}});
const query={sendQuery:true,specifyQuery:'keypair',queryParameters:{parameters:[{name:'incltrip',value:'true'}]}};
const graph={nodes:[read('monitoring','https://api.geliospro.com/api/v1/users/me/monitoring-config'),read('units','https://api.geliospro.com/api/v1/units',query),{id:'publish',data:{n8n:{id:'publish',name:'publish',type:'n8n-nodes-ndc.ndcDataProductPublish',parameters:{dataProductId:'fleet.positions.current.v3'},credentials:{}}}}],edges:[{source:'monitoring',target:'publish'},{source:'units',target:'publish'}]};
const resolved=module.resolveProviderConnectionFromGraph({graph,targetNodeId:'publish',catalog});
if(!validation.ok||catalog.packages?.[0]?.id!=='gelios.provider.v4'||catalog.packages?.[0]?.providerCredential?.credentialType!==slot||!resolved.ok||resolved.descriptor?.providerCredentialRef!=='provider-ref'||resolved.descriptor?.capabilityIds?.join(',')!=='gelios.monitoring_config.current.read,gelios.units.current.read'||resolved.descriptor?.providerRequestNodeIds?.join(',')!=='monitoring,units')process.exit(2);
process.stdout.write('engine-provider-rotating-slot:gelios.provider.v4:ndcProviderRotatingAccessApi:fleet.positions.current.v3:monitoring,units');
""".strip(),
        ),
        "Engine provider rotating slot authority",
        container_id=engine_backend_container_id(),
    )
    expected = (
        "engine-provider-rotating-slot:gelios.provider.v4:"
        "ndcProviderRotatingAccessApi:fleet.positions.current.v3:monitoring,units"
    )
    if live != expected:
        die("Engine provider rotating slot live acceptance mismatch")
    return {
        "target_sha256": dict(ENGINE_PROVIDER_ROTATING_SLOT_TARGET_SHA256),
        "live": live,
    }


def accept_engine_provider_authority_diagnostics_runtime():
    root = component_root("engine")
    validate_engine_provider_authority_diagnostics_slice(
        root,
        ENGINE_PROVIDER_AUTHORITY_DIAGNOSTICS_ARTIFACT_ENTRIES,
    )
    live = run_engine_backend_probe(
        (
            "node",
            "--input-type=module",
            "-e",
            """
const module=await import('file:///app/server/nodeIntelligence/upstreamProjection.js');
const privateValidation={nodeId:'private-1',nodeName:'NDC Data Product Publish',valid:true,errors:[],warnings:[]};
const privateOnly=module.reconcilePrivateNodeValidation({valid:false,errorCount:1,warningCount:0,summary:{errorCount:1,warningCount:0},errors:[{node:'NDC Data Product Publish',message:'Unknown node type: \"ndcDataProductPublish\".'}],warnings:[]},['private-1'],[privateValidation]);
const mixed=module.reconcilePrivateNodeValidation({valid:false,errorCount:2,warningCount:0,summary:{errorCount:2,warningCount:0},errors:[{node:'NDC Data Product Publish',message:'Unknown node type: \"ndcDataProductPublish\".'},{nodeId:'built-in-1',nodeName:'HTTP',message:'URL is required'}],warnings:[]},['private-1'],[privateValidation]);
if(!privateOnly.valid||privateOnly.errors?.length!==0||privateOnly.summary?.errorCount!==0||privateOnly.summary?.warningCount!==1||mixed.valid||mixed.errors?.length!==1||mixed.errors?.[0]?.nodeId!=='built-in-1')process.exit(2);
process.stdout.write('engine-private-node-reconciliation:exact-id-or-name:v1');
""".strip(),
        ),
        "Engine private node validation reconciliation",
        container_id=engine_backend_container_id(),
    )
    expected = "engine-private-node-reconciliation:exact-id-or-name:v1"
    if live != expected:
        die("Engine provider authority diagnostics live acceptance mismatch")
    return {
        "target_sha256": dict(ENGINE_PROVIDER_AUTHORITY_DIAGNOSTICS_TARGET_SHA256),
        "live": live,
    }


def accept_engine_depttrans_zone_authority_v1_runtime():
    root = component_root("engine")
    validate_engine_depttrans_zone_authority_v1_slice(
        root,
        ENGINE_DEPTTRANS_ZONE_AUTHORITY_V1_ARTIFACT_ENTRIES,
    )
    live = run_engine_backend_probe(
        (
            "node",
            "--input-type=module",
            "-e",
            """
const module=await import('file:///app/server/dataProductPublishGrant/providerCatalog.js');
const catalog=await module.loadProviderSecurityCatalog();
const parameters={method:'GET',url:'http://map-gateway:18103/internal/zone-sources/v1/profiles/moscow-pmd-slow-zones/current',authentication:'none',sendQuery:false,sendHeaders:true,specifyHeaders:'keypair',headerParameters:{parameters:[{name:'Accept',value:'application/json'}]},sendBody:false,options:{response:{response:{fullResponse:false,responseFormat:'json'}},allowUnauthorizedCerts:false,redirect:{redirect:{followRedirects:false}},timeout:15000}};
const graph={nodes:[{id:'source',data:{n8n:{id:'source',name:'source',type:'n8n-nodes-base.httpRequest',parameters}}},{id:'publish',data:{n8n:{id:'publish',name:'publish',type:'n8n-nodes-ndc.ndcDataProductPublish',parameters:{dataProductId:'map.zones.current.v2',publishMode:'replace'},credentials:{}}}}],edges:[{source:'source',target:'publish'}]};
const resolved=module.resolveProviderConnectionFromGraph({graph,targetNodeId:'publish',catalog});
const drift=structuredClone(graph);drift.nodes[0].data.n8n.parameters.options.redirect.redirect.followRedirects=true;
const rejected=module.resolveProviderConnectionFromGraph({graph:drift,targetNodeId:'publish',catalog});
if(!module.validateProviderSecurityCatalog(catalog).ok||!resolved.ok||resolved.descriptor?.providerId!=='moscow-department-of-transport'||resolved.descriptor?.authorityBoundary!=='platform-service'||resolved.descriptor?.providerCredentialRef!==null||resolved.descriptor?.platformServiceIds?.join(',')!=='nodedc-map-gateway'||rejected.blockers?.join(',')!=='publish_grant_provider_request_not_exact')process.exit(2);
process.stdout.write('engine-depttrans-zone-authority:platform-service:map.zones.current.v2:nodedc-map-gateway');
""".strip(),
        ),
        "Engine Depttrans zone authority v1",
        container_id=engine_backend_container_id(),
    )
    expected = (
        "engine-depttrans-zone-authority:platform-service:"
        "map.zones.current.v2:nodedc-map-gateway"
    )
    if live != expected:
        die("Engine Depttrans zone authority v1 live acceptance mismatch")
    return {
        "target_sha256": dict(ENGINE_DEPTTRANS_ZONE_AUTHORITY_V1_TARGET_SHA256),
        "live": live,
    }


def accept_engine_provider_target_host_policy_runtime():
    root = component_root("engine")
    validate_engine_provider_target_host_policy_slice(
        root,
        ENGINE_PROVIDER_TARGET_HOST_POLICY_ARTIFACT_ENTRIES,
    )
    live = run_engine_backend_probe(
        (
            "node",
            "--input-type=module",
            "-e",
            """
const module=await import('file:///app/server/routes/n8n.js');
const slot='ndcProviderRotatingAccessApi';
const entry={id:'provider',name:'provider',type:slot,nodeDcCredentialId:'provider-ref',data:{engineAgentAllowedHttpHosts:['*.geliospro.com','telemetry.example']}};
const target={type:'n8n-nodes-base.httpRequest',parameters:{url:'https://api.geliospro.com/api/v1/units'}};
const deniedTarget={type:'n8n-nodes-base.httpRequest',parameters:{url:'https://untrusted.example/collect'}};
const allowed=module.buildEngineAgentCredentialTransportPolicy(entry,{nodes:[]},slot,target);
const denied=module.buildEngineAgentCredentialTransportPolicy(entry,{nodes:[]},slot,deniedTarget);
if(!allowed.bindable||allowed.policy?.allowedHosts?.join(',')!=='api.geliospro.com'||allowed.policy?.requireHttps!==true||allowed.policy?.disableRedirects!==true||denied.bindable||denied.reason!=='credential_host_not_allowed')process.exit(2);
process.stdout.write('engine-provider-target-host-policy:exact-literal-host:v1');
""".strip(),
        ),
        "Engine provider target host policy",
        container_id=engine_backend_container_id(),
    )
    expected = "engine-provider-target-host-policy:exact-literal-host:v1"
    if live != expected:
        die("Engine provider target host policy live acceptance mismatch")
    return {
        "target_sha256": dict(ENGINE_PROVIDER_TARGET_HOST_POLICY_TARGET_SHA256),
        "live": live,
    }


def accept_engine_mcp_execution_profile_decoder_runtime():
    root = component_root("engine")
    validate_engine_mcp_execution_profile_decoder_slice(
        root,
        ENGINE_MCP_EXECUTION_PROFILE_DECODER_ARTIFACT_ENTRIES,
    )
    live = run_engine_backend_probe(
        (
            "node",
            "--input-type=module",
            "-e",
            """
const module=await import('file:///app/server/routes/n8n.js');
const execution={id:'profile-decoder-acceptance',data:JSON.stringify([{resultData:'1'},{runData:'2'},{Probe:'3'},['4'],{data:'5'},{main:'6'},[['7']],{json:'8'},{params:'9'},{VS_43:'10',mcc:'11',sats:9},'16','250'])};
const profile=module.toSafeNodeOutputProfile(execution,'Probe');
const paths=new Map(profile.paths.map((item)=>[item.path,item]));
if(!profile.found||profile.valuesIncluded!==false||paths.get('$.params.VS_43')?.types?.join(',')!=='string'||paths.get('$.params.VS_43')?.minLength!==2||paths.get('$.params.mcc')?.types?.join(',')!=='string'||paths.get('$.params.mcc')?.minLength!==3||paths.get('$.params.sats')?.types?.join(',')!=='number'||profile.paths.some((item)=>item.path.includes('.json.fact')))process.exit(2);
process.stdout.write('engine-mcp-execution-profile-decoder:flatted-numeric-strings:safe-profile:v1');
""".strip(),
        ),
        "Engine MCP execution profile decoder",
        container_id=engine_backend_container_id(),
    )
    expected = (
        "engine-mcp-execution-profile-decoder:"
        "flatted-numeric-strings:safe-profile:v1"
    )
    if live != expected:
        die("Engine MCP execution profile decoder live acceptance mismatch")
    return {
        "target_sha256": dict(ENGINE_MCP_EXECUTION_PROFILE_DECODER_TARGET_SHA256),
        "live": live,
    }


def accept_engine_mcp_telemetry_catalog_runtime():
    root = component_root("engine")
    validate_engine_mcp_telemetry_catalog_slice(
        root,
        ENGINE_MCP_TELEMETRY_CATALOG_ARTIFACT_ENTRIES,
    )
    live = run_engine_backend_probe(
        (
            "node",
            "--input-type=module",
            "-e",
            """
const n8n=await import('file:///app/server/routes/n8n.js');
const gateway=await import('file:///app/server/routes/engineAgentGateway.js');
const execution={id:'telemetry-catalog-acceptance',data:{resultData:{runData:{Mapper:[{data:{main:[[{json:{fact:{attributes:{sensor_readings:[{id:'engine.rpm',label:'Engine RPM',unit:'rpm',value:1350},{id:'tracker.status',label:'Bearer provider-token-must-not-escape',value:'provider-token-must-not-escape'}]}},lastMsg:{params:{sensor_readings:[{id:'raw.must-not-enter',label:'Raw',value:'raw-provider-value'}]}}}}]]}}]}}}};
const catalog=n8n.toSafeTelemetryReadingCatalog(execution,'Mapper');
const rpm=catalog.readings.find((item)=>item.id==='engine.rpm');
const status=catalog.readings.find((item)=>item.id==='tracker.status');
const serialized=JSON.stringify(catalog);
const tool=gateway.engineAgentTools.find((item)=>item.name==='engine_get_telemetry_reading_catalog');
if(gateway.ENGINE_AGENT_MCP_VERSION!=='0.8.0'||!tool||!catalog.found||catalog.valuesIncluded!==false||catalog.rawExecutionDataIncluded!==false||rpm?.label!=='Engine RPM'||rpm?.unit!=='rpm'||rpm?.valueTypes?.join(',')!=='number'||status?.label!==undefined||catalog.readings.some((item)=>item.id==='raw.must-not-enter')||serialized.includes('1350')||serialized.includes('provider-token-must-not-escape')||serialized.includes('raw-provider-value'))process.exit(2);
process.stdout.write('engine-mcp-telemetry-catalog:0.8.0:normalized-metadata-only:v1');
""".strip(),
        ),
        "Engine MCP telemetry reading catalog",
        container_id=engine_backend_container_id(),
    )
    expected = "engine-mcp-telemetry-catalog:0.8.0:normalized-metadata-only:v1"
    if live != expected:
        die("Engine MCP telemetry reading catalog live acceptance mismatch")
    return {
        "target_sha256": dict(ENGINE_MCP_TELEMETRY_CATALOG_TARGET_SHA256),
        "live": live,
    }


def accept_engine_mcp_execution_plan_materialization_runtime():
    root = component_root("engine")
    validate_engine_mcp_execution_plan_materialization_slice(
        root,
        ENGINE_MCP_EXECUTION_PLAN_MATERIALIZATION_ARTIFACT_ENTRIES,
    )
    live = run_engine_backend_probe(
        (
            "node",
            "--input-type=module",
            "-e",
            """
const fs=await import('node:fs/promises');
const gateway=await import('file:///app/server/routes/engineAgentGateway.js');
const catalogModule=await import('file:///app/server/l2ExecutionPlan/catalog.js');
const materializer=await import('file:///app/server/l2ExecutionPlan/materializer.js');
const catalog=await catalogModule.loadExecutionPlanCatalog();
const plan=gateway.engineAgentTools.find((item)=>item.name==='engine_plan_l2_execution_plan_materialization');
const apply=gateway.engineAgentTools.find((item)=>item.name==='engine_apply_l2_execution_plan_materialization');
const planRequired=plan?.inputSchema?.required||[];
const applyRequired=apply?.inputSchema?.required||[];
const genericSource=(await Promise.all(['/app/server/l2ExecutionPlan/compiler.js','/app/server/l2ExecutionPlan/materializer.js'].map((path)=>fs.readFile(path,'utf8')))).join('\\n');
const unmanaged=materializer.materializationState({source:{},nodes:[{id:'existing'}],edges:[]});
if(gateway.ENGINE_AGENT_MCP_VERSION!=='0.9.0'||!plan||!apply||plan?.inputSchema?.additionalProperties!==false||apply?.inputSchema?.additionalProperties!==false||!planRequired.includes('executionPlan')||!applyRequired.includes('planRef')||!applyRequired.includes('providerAuthRef')||catalog.schemaVersion!=='nodedc.engine.execution-plan-catalog/v1'||catalog.runtime?.graphBlueprintSchemaVersion!=='nodedc.l2-graph-blueprint/v1'||catalog.runtime?.compilerVersions?.join(',')!=='1.1.0'||unmanaged!=='unmanaged_existing'||/gelios|robot2b/i.test(genericSource))process.exit(2);
process.stdout.write('engine-mcp-execution-plan-materialization:0.9.0:provider-package-authority:two-phase:v1');
""".strip(),
        ),
        "Engine MCP execution plan materialization",
        container_id=engine_backend_container_id(),
    )
    expected = (
        "engine-mcp-execution-plan-materialization:"
        "0.9.0:provider-package-authority:two-phase:v1"
    )
    if live != expected:
        die("Engine MCP execution plan materialization live acceptance mismatch")
    return {
        "target_sha256": dict(
            ENGINE_MCP_EXECUTION_PLAN_MATERIALIZATION_TARGET_SHA256
        ),
        "live": live,
    }


def accept_engine_mcp_execution_plan_telemetry_runtime():
    root = component_root("engine")
    validate_engine_mcp_execution_plan_telemetry_runtime_slice(
        root,
        ENGINE_MCP_EXECUTION_PLAN_TELEMETRY_RUNTIME_ARTIFACT_ENTRIES,
    )
    live = run_engine_backend_probe(
        (
            "node",
            "--input-type=module",
            "-e",
            """
const fs=await import('node:fs/promises');
const catalogModule=await import('file:///app/server/l2ExecutionPlan/catalog.js');
const catalog=await catalogModule.loadExecutionPlanCatalog();
const compiler=await fs.readFile('/app/server/l2ExecutionPlan/compiler.js','utf8');
const versions=catalog.runtime?.compilerVersions||[];
if(versions.join(',')!=='1.1.0,1.2.0'||!compiler.includes("if (compilerVersion === '1.1.0')")||!compiler.includes("if (compilerVersion !== '1.2.0')")||!compiler.includes('"msgParam", "msg_param"')||!compiler.includes('descriptor.telemetryProjection')||!compiler.includes('"message-param"')||!compiler.includes('convertedSensorValue')||!compiler.includes('visibleSensorDefinition')||/gelios|robot2b/i.test(compiler))process.exit(2);
process.stdout.write('engine-mcp-execution-plan-telemetry-runtime:0.9.0:compiler-1.2.0:declared-projected:v2');
""".strip(),
        ),
        "Engine MCP execution plan telemetry runtime",
        container_id=engine_backend_container_id(),
    )
    expected = (
        "engine-mcp-execution-plan-telemetry-runtime:"
        "0.9.0:compiler-1.2.0:declared-projected:v2"
    )
    if live != expected:
        die("Engine MCP execution plan telemetry runtime live acceptance mismatch")
    return {
        "target_sha256": dict(
            ENGINE_MCP_EXECUTION_PLAN_TELEMETRY_RUNTIME_TARGET_SHA256
        ),
        "live": live,
    }


def accept_engine_mcp_execution_plan_module_ownership_runtime():
    root = component_root("engine")
    validate_engine_mcp_execution_plan_module_ownership_slice(
        root,
        ENGINE_MCP_EXECUTION_PLAN_MODULE_OWNERSHIP_ARTIFACT_ENTRIES,
    )
    live = run_engine_backend_probe(
        (
            "node",
            "--input-type=module",
            "-e",
            """
const fs=await import('node:fs/promises');
const gateway=await import('file:///app/server/routes/engineAgentGateway.js');
const catalogModule=await import('file:///app/server/l2ExecutionPlan/catalog.js');
const materializer=await import('file:///app/server/l2ExecutionPlan/materializer.js');
const catalog=await catalogModule.loadExecutionPlanCatalog();
const source=await fs.readFile('/app/server/l2ExecutionPlan/materializer.js','utf8');
const plan=gateway.engineAgentTools.find((item)=>item.name==='engine_plan_l2_execution_plan_materialization');
const strategies=plan?.inputSchema?.properties?.strategy?.enum||[];
const adoption=plan?.inputSchema?.properties?.moduleAdoption?.properties||{};
const geliosV9=catalog.packages?.find((item)=>item.id==='gelios.provider.v9');
const legacy=catalog.packages?.some((item)=>item.id==='gelios.provider.v8');
const unmanaged=materializer.materializationState({source:{},nodes:[{id:'existing'}],edges:[]});
if(gateway.ENGINE_AGENT_MCP_VERSION!=='0.10.0'||strategies.join(',')!=='create_or_reconcile_owned,adopt_existing,adopt_existing_module'||!adoption.preserveBoundNodeIds||!source.includes('execution_plan_module_retire_boundary_not_closed')||!source.includes('manual_webhook_same_method')||/gelios|robot2b/i.test(source)||geliosV9?.contractDigest!=='sha256:7dd4ce4a45ce76e884ffa1e304bfaa521f552e9a45e535930f2d17b882ae23ed'||!legacy||unmanaged!=='unmanaged_existing')process.exit(2);
process.stdout.write('engine-mcp-execution-plan-module-ownership:0.10.0:module-scoped:shared-boundary:v3');
""".strip(),
        ),
        "Engine MCP execution plan module ownership",
        container_id=engine_backend_container_id(),
    )
    expected = (
        "engine-mcp-execution-plan-module-ownership:"
        "0.10.0:module-scoped:shared-boundary:v3"
    )
    if live != expected:
        die(
            "Engine MCP execution plan module ownership live acceptance "
            "mismatch"
        )
    return {
        "target_sha256": dict(
            ENGINE_MCP_EXECUTION_PLAN_MODULE_OWNERSHIP_TARGET_SHA256
        ),
        "live": live,
    }


def accept_engine_mcp_normalized_identity_search_runtime():
    root = component_root("engine")
    validate_engine_mcp_normalized_identity_search_slice(
        root,
        ENGINE_MCP_NORMALIZED_IDENTITY_SEARCH_ARTIFACT_ENTRIES,
    )
    live = run_engine_backend_probe(
        (
            "node",
            "--input-type=module",
            "-e",
            """
const fs=await import('node:fs/promises');
const gateway=await import('file:///app/server/routes/engineAgentGateway.js');
const executionCatalog=JSON.parse(await fs.readFile('/app/server/assets/execution-plans/v1/catalog.json','utf8'));
const securityCatalog=JSON.parse(await fs.readFile('/app/server/assets/provider-packages/v1/catalog.json','utf8'));
const route=await fs.readFile('/app/server/routes/n8n.js','utf8');
const compiler=await fs.readFile('/app/server/l2ExecutionPlan/compiler.js','utf8');
const tool=gateway.engineAgentTools.find((item)=>item.name==='engine_find_normalized_subjects');
const packageV11=executionCatalog.packages?.find((item)=>item.id==='gelios.provider.v11');
const securityV11=securityCatalog.packages?.find((item)=>item.id==='gelios.provider.v11');
const identityProfile=packageV11?.profiles?.find((item)=>item.dataProductId==='fleet.units.identity.current.v1');
const identityCapability=securityV11?.capabilities?.find((item)=>item.id==='gelios.units.identity.read');
if(gateway.ENGINE_AGENT_MCP_VERSION!=='0.11.0'||!tool?.inputSchema?.properties?.boundingBox||!tool?.inputSchema?.properties?.fields||!route.includes('normalizedFactsOnly: true')||!route.includes('rawExecutionDataIncluded: false')||!route.includes('commandSurfaceIncluded: false')||!compiler.includes('boundedStringList')||!compiler.includes('boundedNamedValues')||/gelios|robot2b/i.test(compiler)||executionCatalog.runtime?.compilerVersions?.join(',')!=='1.1.0,1.2.0,1.3.0,1.4.0'||packageV11?.contractDigest!=='sha256:4bf211d9ed6cfd227df444d49d8c5ce77a24389ed2ba3d159d53d83e0d4738d9'||!identityProfile||identityCapability?.classification!=='read'||identityCapability?.dataProductIds?.join(',')!=='fleet.units.identity.current.v1')process.exit(2);
process.stdout.write('engine-mcp-normalized-identity-search:0.11.0:canonical-facts:full-admin-identifiers:read-only:v1');
""".strip(),
        ),
        "Engine MCP normalized identity search",
        container_id=engine_backend_container_id(),
    )
    expected = (
        "engine-mcp-normalized-identity-search:"
        "0.11.0:canonical-facts:full-admin-identifiers:read-only:v1"
    )
    if live != expected:
        die("Engine MCP normalized identity search live acceptance mismatch")
    return {
        "target_sha256": dict(
            ENGINE_MCP_NORMALIZED_IDENTITY_SEARCH_TARGET_SHA256
        ),
        "live": live,
    }


def accept_engine_mcp_execution_plan_sandbox_runtime():
    root = component_root("engine")
    validate_engine_mcp_execution_plan_sandbox_runtime_slice(
        root,
        ENGINE_MCP_EXECUTION_PLAN_SANDBOX_RUNTIME_ARTIFACT_ENTRIES,
    )
    live = run_engine_backend_probe(
        (
            "node",
            "--input-type=module",
            "-e",
            """
const fs=await import('node:fs/promises');
const compiler=await fs.readFile('/app/server/l2ExecutionPlan/compiler.js','utf8');
const start=compiler.indexOf('const encodedBytes = (value) => {');
const end=compiler.indexOf('for (const raw of input) {',start);
const byteCounter=start>=0&&end>start?compiler.slice(start,end):'';
if(!byteCounter.includes('encoded.charCodeAt(index)')||!byteCounter.includes('length += 4')||byteCounter.includes('TextEncoder')||!compiler.includes('return extracted.map((source) => ({ json: { source, collectionReceivedAt: receivedAt } }))')||/gelios|robot2b/i.test(compiler))process.exit(2);
process.stdout.write('engine-mcp-execution-plan-sandbox-runtime:0.11.0:n8n-2.3.2:pure-js-utf8:v4');
""".strip(),
        ),
        "Engine MCP execution plan sandbox runtime",
        container_id=engine_backend_container_id(),
    )
    expected = (
        "engine-mcp-execution-plan-sandbox-runtime:"
        "0.11.0:n8n-2.3.2:pure-js-utf8:v4"
    )
    if live != expected:
        die("Engine MCP execution plan sandbox runtime live acceptance mismatch")
    return {
        "target_sha256": dict(
            ENGINE_MCP_EXECUTION_PLAN_SANDBOX_RUNTIME_TARGET_SHA256
        ),
        "live": live,
    }


def accept_engine_mcp_gelios_items_envelope_runtime():
    root = component_root("engine")
    validate_engine_mcp_gelios_items_envelope_slice(
        root,
        ENGINE_MCP_GELIOS_ITEMS_ENVELOPE_ARTIFACT_ENTRIES,
    )
    live = run_engine_backend_probe(
        (
            "node",
            "--input-type=module",
            "-e",
            """
const fs=await import('node:fs/promises');
const execution=JSON.parse(await fs.readFile('/app/server/assets/execution-plans/v1/catalog.json','utf8'));
const security=JSON.parse(await fs.readFile('/app/server/assets/provider-packages/v1/catalog.json','utf8'));
const compiler=await fs.readFile('/app/server/l2ExecutionPlan/compiler.js','utf8');
const ids=execution.packages.map(({id})=>id);
const v12=execution.packages.find(({id})=>id==='gelios.provider.v12');
const identity=v12?.profiles?.filter(({id,dataProductId})=>id==='gelios.units.identity.warm.v1'&&dataProductId==='fleet.units.identity.current.v1')||[];
const authorities=security.packages.filter(({capabilities=[]})=>capabilities.some(({dataProductIds=[]})=>dataProductIds.includes('fleet.units.identity.current.v1')));
if(!ids.includes('gelios.provider.v11')||v12?.version!=='12.0.0'||identity.length!==1||authorities.length!==1||authorities[0].id!=='gelios.provider.v12'||/gelios|robot2b/i.test(compiler)||compiler.includes('TextEncoder'))process.exit(2);
process.stdout.write('engine-mcp-gelios-items-envelope:0.11.0:v11-history:v12-authority:items');
""".strip(),
        ),
        "Engine MCP Gelios items envelope",
        container_id=engine_backend_container_id(),
    )
    expected = (
        "engine-mcp-gelios-items-envelope:"
        "0.11.0:v11-history:v12-authority:items"
    )
    if live != expected:
        die("Engine MCP Gelios items envelope live acceptance mismatch")
    return {
        "target_sha256": dict(
            ENGINE_MCP_GELIOS_ITEMS_ENVELOPE_TARGET_SHA256
        ),
        "live": live,
    }


def accept_engine_mcp_registered_execution_profiles_runtime():
    root = component_root("engine")
    validate_engine_mcp_registered_execution_profiles_slice(
        root,
        ENGINE_MCP_REGISTERED_EXECUTION_PROFILES_ARTIFACT_ENTRIES,
    )
    live = run_engine_backend_probe(
        (
            "node",
            "--input-type=module",
            "-e",
            """
const gateway=await import('file:///app/server/routes/engineAgentGateway.js');
const catalogModule=await import('file:///app/server/l2ExecutionPlan/catalog.js');
const registeredModule=await import('file:///app/server/l2ExecutionPlan/registeredProfiles.js');
const catalog=await catalogModule.loadExecutionPlanCatalog();
let captured=null;
const service=registeredModule.createRegisteredExecutionProfileService({
  loadCatalog:async()=>catalog,
  planMaterialization:async(input)=>{captured=input;return {ok:true,status:'planned',planRef:'emplan_probe',providerAuthRefs:[]};},
});
const target={workflowId:'workflow-probe',nodeId:'node-probe'};
const listed=await service.list({actorKey:'actor-probe',target});
const profile=listed.profiles.find(({profile})=>profile.id==='gelios.units.profile.cold.v1');
if(gateway.ENGINE_AGENT_MCP_VERSION!=='0.12.0'||!gateway.engineAgentTools.some(({name})=>name==='engine_list_l2_execution_profiles')||!gateway.engineAgentTools.some(({name})=>name==='engine_plan_registered_l2_execution')||listed.count!==6||!profile||JSON.stringify(listed).includes('executionPlanTemplate'))process.exit(2);
await service.plan({actorKey:'actor-probe',target,profileRef:profile.profileRef,expectedRevision:'revision-probe',strategy:'create_or_reconcile_owned',expectedScope:{tenantId:'tenant-probe',connectionId:'connection-probe'}});
if(captured?.executionPlan?.connection?.tenantId!=='tenant-probe'||captured?.executionPlan?.connection?.connectionId!=='connection-probe'||!String(captured?.executionPlan?.bindings?.provider?.reference||'').startsWith('ndc-credref:engine-target-'))process.exit(3);
process.stdout.write('engine-mcp-registered-execution-profiles:0.12.0:profiles-6:target-scope:existing-materializer');
""".strip(),
        ),
        "Engine MCP registered execution profiles",
        container_id=engine_backend_container_id(),
    )
    expected = (
        "engine-mcp-registered-execution-profiles:"
        "0.12.0:profiles-6:target-scope:existing-materializer"
    )
    if live != expected:
        die("Engine MCP registered execution profiles live acceptance mismatch")
    return {
        "target_sha256": dict(
            ENGINE_MCP_REGISTERED_EXECUTION_PROFILES_TARGET_SHA256
        ),
        "live": live,
    }


def accept_engine_mcp_gelios_units_items_runtime():
    root = component_root("engine")
    validate_engine_mcp_gelios_units_items_slice(
        root,
        ENGINE_MCP_GELIOS_UNITS_ITEMS_ARTIFACT_ENTRIES,
    )
    live = run_engine_backend_probe(
        (
            "node",
            "--input-type=module",
            "-e",
            """
const gateway=await import('file:///app/server/routes/engineAgentGateway.js');
const executionModule=await import('file:///app/server/l2ExecutionPlan/catalog.js');
const securityModule=await import('file:///app/server/dataProductPublishGrant/providerCatalog.js');
const execution=await executionModule.loadExecutionPlanCatalog();
const security=await securityModule.loadProviderSecurityCatalog();
const provider=execution.packages.find((item)=>item.id==='gelios.provider.v12');
const profile=provider?.profiles.find((item)=>item.id==='gelios.units.profile.cold.v1');
const plan=profile?.executionPlanTemplate;
const extract=plan?.steps.find((step)=>step.kind==='extract_items'&&step.config?.capabilityId==='gelios.units.current.read');
const secureProvider=security.packages.find((item)=>item.id==='gelios.provider.v12');
if(gateway.ENGINE_AGENT_MCP_VERSION!=='0.12.0'||!gateway.engineAgentTools.some(({name})=>name==='engine_list_l2_execution_profiles')||!gateway.engineAgentTools.some(({name})=>name==='engine_plan_registered_l2_execution')||provider?.version!=='12.0.1'||secureProvider?.version!=='12.0.1'||plan?.compilerVersion!=='1.4.0'||extract?.config?.response?.collectionPaths?.[0]!=='items')process.exit(2);
process.stdout.write('engine-mcp-gelios-units-items:0.12.0:gelios.provider.v12@12.0.1:technical-profile:items');
""".strip(),
        ),
        "Engine MCP Gelios units items envelope",
        container_id=engine_backend_container_id(),
    )
    expected = (
        "engine-mcp-gelios-units-items:0.12.0:"
        "gelios.provider.v12@12.0.1:technical-profile:items"
    )
    if live != expected:
        die("Engine MCP Gelios units items live acceptance mismatch")
    return {
        "target_sha256": dict(
            ENGINE_MCP_GELIOS_UNITS_ITEMS_TARGET_SHA256
        ),
        "live": live,
    }


def accept_engine_mcp_l1_credential_reuse_runtime():
    root = component_root("engine")
    validate_engine_mcp_l1_credential_reuse_slice(
        root,
        ENGINE_MCP_L1_CREDENTIAL_REUSE_ARTIFACT_ENTRIES,
    )
    live = run_engine_backend_probe(
        (
            "node",
            "--input-type=module",
            "-e",
            """
const route=await import('file:///app/server/routes/n8n.js');
const slot='httpBearerAuth';
const entry={nodeDcCredentialId:'credential-provider',n8nCredentialId:'runtime-provider',type:slot,name:'Provider read access',source:'manual',status:'ok',data:{token:'synthetic'}};
const sameL1=new Set([entry.nodeDcCredentialId]);
const otherL1=new Set(['credential-other']);
const graph={nodes:[{id:'source-reader',data:{n8n:{type:'n8n-nodes-base.httpRequest',parameters:{url:'https://api.provider.example/v1/items'},credentials:{[slot]:{id:entry.n8nCredentialId,name:entry.name,nodeDcCredentialId:entry.nodeDcCredentialId}}}}}]};
const target={type:'n8n-nodes-base.httpRequest',parameters:{url:'https://api.provider.example/v1/identity'}};
const deniedTarget={type:'n8n-nodes-base.httpRequest',parameters:{url:'https://untrusted.example/collect'}};
const allowed=route.buildEngineAgentCredentialTransportPolicy({...entry,data:{allowedHttpRequestDomains:'all'}},graph,slot,target);
const denied=route.buildEngineAgentCredentialTransportPolicy({...entry,data:{allowedHttpRequestDomains:'all'}},graph,slot,deniedTarget);
if(route.engineAgentCandidateScope(entry,{localEntries:[]},sameL1)!=='l1'||route.engineAgentCandidateScope(entry,{localEntries:[]},otherL1)!==''||route.engineAgentCredentialMayReuseWithinL1({...entry,source:'workflow-inline'})||!allowed.bindable||allowed.policy?.allowedHosts?.join(',')!=='api.provider.example'||denied.bindable)process.exit(2);
process.stdout.write('engine-mcp-l1-credential-reuse:0.11.0:same-l1:opaque-ref:v1');
""".strip(),
        ),
        "Engine MCP L1 credential reuse",
        container_id=engine_backend_container_id(),
    )
    expected = (
        "engine-mcp-l1-credential-reuse:"
        "0.11.0:same-l1:opaque-ref:v1"
    )
    if live != expected:
        die("Engine MCP L1 credential reuse live acceptance mismatch")
    return {
        "target_sha256": dict(ENGINE_MCP_L1_CREDENTIAL_REUSE_TARGET_SHA256),
        "live": live,
    }


def accept_engine_mcp_l1_credential_provenance_runtime():
    root = component_root("engine")
    validate_engine_mcp_l1_credential_provenance_slice(
        root,
        ENGINE_MCP_L1_CREDENTIAL_PROVENANCE_ARTIFACT_ENTRIES,
    )
    live = run_engine_backend_probe(
        (
            "node",
            "--input-type=module",
            "-e",
            """
const route=await import('file:///app/server/routes/n8n.js');
const slot='httpBearerAuth';
const common={nodeDcCredentialId:'credential-provider',n8nCredentialId:'runtime-provider',type:slot,name:'Provider read access',source:'manual',status:'ok',data:{token:'synthetic'}};
const workflowRef={...common,source:'workflow-ref'};
const workflowRefWithoutSync={...workflowRef,data:{}};
const sameL1=new Set([common.nodeDcCredentialId]);
const graph={nodes:[{id:'source-reader',data:{n8n:{type:'n8n-nodes-base.httpRequest',parameters:{url:'https://api.provider.example/v1/items'},credentials:{[slot]:{id:common.n8nCredentialId,name:common.name,nodeDcCredentialId:common.nodeDcCredentialId}}}}}]};
const target={type:'n8n-nodes-base.httpRequest',parameters:{url:'https://api.provider.example/v1/identity'}};
const allowed=route.buildEngineAgentCredentialTransportPolicy({...common,data:{allowedHttpRequestDomains:'all'}},graph,slot,target);
if(!route.engineAgentCredentialMayProveL1Provenance(workflowRef)||route.engineAgentCredentialMayProveL1Provenance(workflowRefWithoutSync)||route.engineAgentCredentialMayReuseWithinL1(workflowRef)||route.engineAgentCandidateScope(common,{localEntries:[]},sameL1)!=='l1'||!allowed.bindable||allowed.policy?.allowedHosts?.join(',')!=='api.provider.example')process.exit(2);
process.stdout.write('engine-mcp-l1-credential-provenance:0.11.0:workflow-ref-sync-proof:v2');
""".strip(),
        ),
        "Engine MCP L1 credential provenance",
        container_id=engine_backend_container_id(),
    )
    expected = (
        "engine-mcp-l1-credential-provenance:"
        "0.11.0:workflow-ref-sync-proof:v2"
    )
    if live != expected:
        die("Engine MCP L1 credential provenance live acceptance mismatch")
    return {
        "target_sha256": dict(
            ENGINE_MCP_L1_CREDENTIAL_PROVENANCE_TARGET_SHA256
        ),
        "live": live,
    }


def validate_no_lifecycle_scripts(payload_dir, label):
    forbidden = ("preinstall", "install", "postinstall", "prepare", "prepack", "postpack")
    for package_path in payload_dir.rglob("package.json"):
        package = read_strict_json(package_path, f"{label} package.json", max_bytes=1024 * 1024)
        scripts = package.get("scripts") or {}
        if not isinstance(scripts, dict):
            die(f"{label} package scripts must be an object")
        for name in forbidden:
            if name in scripts:
                die(f"{label} lifecycle script is forbidden: {package_path.relative_to(payload_dir)}:{name}")


def expected_engine_credential_backend_override():
    return "\n".join((
        "services:",
        "  nodedc-backend:",
        f"    image: {ENGINE_CREDENTIAL_BACKEND_IMAGE}",
        "    pull_policy: never",
        "    environment:",
        "      HOME: /tmp",
        "    command:",
        "      - /bin/sh",
        "      - -lc",
        "      - |-|".replace("|-|", "|-"),
        "        set -eu",
        "        test \"$$(command -v node)\" = /usr/local/bin/node",
        "        command -v sqlite3 >/dev/null",
        "        command -v docker >/dev/null",
        "        docker compose version >/dev/null",
        f"        test \"$$(sha256sum /app/package-lock.json | cut -d ' ' -f 1)\" = {ENGINE_CREDENTIAL_BACKEND_PACKAGE_LOCK_SHA256}",
        "        test -d /app/node_modules",
        "        mkdir -p /app/server/data/api",
        "        if [ -d /seed-api ]; then",
        "          for d in cesium gelios overpass wind yandex; do",
        "            src=/seed-api/$$d",
        "            [ -d \"$$src\" ] || continue",
        "            dst=/app/server/data/api/$$d",
        "            mkdir -p \"$$dst\"",
        "            if [ \"$$NODEDC_API_SEED_MODE\" = force ]; then",
        "              cp -R \"$$src/.\" \"$$dst/\"",
        "            elif [ -z \"$$(ls -A \"$$dst\" 2>/dev/null)\" ]; then",
        "              cp -R \"$$src/.\" \"$$dst/\"",
        "            fi",
        "          done",
        "        fi",
        "        if [ \"$$NODEDC_DATA_SEED_MODE\" != off ] && [ \"$$NODEDC_DATA_SEED_MODE\" != none ]; then",
        "          for d in workflows n8n; do",
        "            src=/seed-data/$$d",
        "            dst=/app/server/data/$$d",
        "            [ -d \"$$src\" ] || continue",
        "            mkdir -p \"$$dst\"",
        "            if [ \"$$NODEDC_DATA_SEED_MODE\" = merge ] || [ \"$$NODEDC_DATA_SEED_MODE\" = force ]; then",
        "              cp -R \"$$src/.\" \"$$dst/\"",
        "            elif [ -z \"$$(ls -A \"$$dst\" 2>/dev/null)\" ]; then",
        "              cp -R \"$$src/.\" \"$$dst/\"",
        "            fi",
        "          done",
        "        fi",
        "        exec node server/index.js",
        "    volumes:",
        "      - ./nodedc-backend-node_modules:/app/node_modules:ro",
        "    tmpfs:",
        "      - /tmp:mode=1777",
        "      - /run:mode=0755",
        "      - /var/cache:mode=0755",
        "      - /var/log:mode=0755",
        "",
    ))


def expected_engine_data_product_publish_grant_override():
    return "\n".join((
        "services:",
        "  nodedc-backend:",
        '    user: "0:0"',
        "    environment:",
        f"      ENGINE_DATA_PLANE_BASE_URL: {EXTERNAL_DATA_PLANE_INTERNAL_URL}",
        f"      ENGINE_EDP_MANAGED_PROVISIONER_PRIVATE_KEY_FILE: {ENGINE_EDP_PRIVATE_KEY_CONTAINER_PATH}",
        f"      ENGINE_CONTROL_PLANE_PUBLISH_GRANT_ROOT: {ENGINE_PUBLISH_GRANT_CONTAINER_PATH}",
        "    volumes:",
        "      - type: bind",
        f"        source: {ENGINE_PUBLISH_GRANT_STATE_PATH}",
        f"        target: {ENGINE_PUBLISH_GRANT_CONTAINER_PATH}",
        "        bind:",
        "          create_host_path: false",
        "      - type: bind",
        f"        source: {ENGINE_EDP_MANAGED_PROVISIONER_PRIVATE_KEY_FILE}",
        f"        target: {ENGINE_EDP_PRIVATE_KEY_CONTAINER_PATH}",
        "        read_only: true",
        "        bind:",
        "          create_host_path: false",
        "",
    ))


def expected_engine_data_product_read_grant_override():
    return "\n".join((
        "services:",
        "  nodedc-backend:",
        "    environment:",
        f"      ENGINE_CONTROL_PLANE_READ_GRANT_ROOT: {ENGINE_READ_GRANT_CONTAINER_PATH}",
        "    volumes:",
        "      - type: bind",
        f"        source: {ENGINE_READ_GRANT_STATE_PATH}",
        f"        target: {ENGINE_READ_GRANT_CONTAINER_PATH}",
        "        bind:",
        "          create_host_path: false",
        "",
    ))


def validate_engine_credential_sink_slice(payload_dir, entries):
    if tuple(entries) != ENGINE_CREDENTIAL_SINK_ARTIFACT_ENTRIES:
        die("Engine credential sink files.txt exact set/order mismatch")
    index_text = (payload_dir / "nodedc-source/server/index.js").read_text(encoding="utf-8")
    if "engineCredentialSink" not in index_text:
        die("Engine credential sink router mount is missing")
    vendor_contract = payload_dir / "nodedc-source/server/credentialSink/vendor/engine-credential-sink.mjs"
    if sha256_file(vendor_contract) != ENGINE_CREDENTIAL_SINK_CONTRACT_SHA256:
        die("Engine credential sink vendored contract sha256 mismatch")
    override = payload_dir / ENGINE_CREDENTIAL_BACKEND_OVERRIDE_TEMPLATE_REL
    try:
        override_text = override.read_text(encoding="utf-8")
    except (OSError, UnicodeDecodeError):
        die("Engine credential immutable runtime override is unreadable")
    if override_text != expected_engine_credential_backend_override():
        die("Engine credential immutable runtime override mismatch")
    if re.search(r"\b(?:apk|npm|yarn|pnpm)\b", override_text):
        die("Engine credential mutable runtime setup is forbidden")
    generic_roots = (
        payload_dir / "nodedc-source/server/credentialSink",
        payload_dir / "nodedc-source/server/credentialPolicies/ndcPrivateNode.js",
        payload_dir / "nodedc-source/server/routes/engineCredentialSink.js",
    )
    for root in generic_roots:
        candidates = [root] if root.is_file() else list(root.rglob("*"))
        for path in candidates:
            if not path.is_file() or path.suffix.lower() not in (".js", ".mjs", ".json"):
                continue
            try:
                text_value = path.read_text(encoding="utf-8")
            except (OSError, UnicodeDecodeError):
                die(f"Engine credential sink source is unreadable: {path.relative_to(payload_dir)}")
            if re.search(r"gelios|robot2b", text_value, re.IGNORECASE):
                die(f"Engine credential sink provider logic is forbidden: {path.relative_to(payload_dir)}")
    validate_no_lifecycle_scripts(payload_dir, "Engine credential sink")


def validate_engine_data_product_publish_grant_slice(payload_dir, entries):
    if tuple(entries) != ENGINE_DATA_PRODUCT_PUBLISH_GRANT_ARTIFACT_ENTRIES:
        die("Engine data product publish grant files.txt exact set/order mismatch")

    override = payload_dir / ENGINE_DATA_PRODUCT_PUBLISH_GRANT_OVERRIDE_REL
    try:
        override_text = override.read_text(encoding="utf-8")
    except (OSError, UnicodeDecodeError):
        die("Engine data product publish grant runtime override is unreadable")
    if override_text != expected_engine_data_product_publish_grant_override():
        die("Engine data product publish grant runtime override mismatch")

    n8n_route = (payload_dir / "nodedc-source/server/routes/n8n.js").read_text(encoding="utf-8")
    if "from '../credentialSink/" in n8n_route:
        die("Engine data product publish grant must not depend on the legacy sink")
    for adapter in (
        "engineCredentialSinkN8nAdapter",
        "engineDataProductPublishGrantN8nAdapter",
    ):
        if adapter not in n8n_route:
            die(f"Engine data product publish grant adapter is missing: {adapter}")

    gateway = (payload_dir / "nodedc-source/server/routes/engineAgentGateway.js").read_text(
        encoding="utf-8"
    )
    for tool in (
        "engine_plan_data_product_publish_grant",
        "engine_apply_data_product_publish_grant",
        "engine_accept_data_product_publish_grant",
        "engine_rollback_data_product_publish_grant",
    ):
        if tool not in gateway:
            die(f"Engine data product publish grant tool is missing: {tool}")

    catalog_path = payload_dir / ENGINE_PROVIDER_SECURITY_CATALOG_REL
    if sha256_file(catalog_path) == ENGINE_PUBLISH_GRANT_COMPOSITE_PROVIDER_CATALOG_TARGET_SHA256:
        catalog = read_strict_json(catalog_path, "Engine composite provider security catalog")
        packages = catalog.get("packages") if isinstance(catalog, dict) else None
        provider = packages[0] if isinstance(packages, list) and len(packages) == 1 else None
        capabilities = provider.get("capabilities") if isinstance(provider, dict) else None
        if (
            catalog.get("schemaVersion") != "nodedc.engine.provider-security-catalog/v1"
            or not isinstance(provider, dict)
            or provider.get("id") != "gelios.provider.v4"
            or provider.get("version") != "4.0.0"
            or provider.get("providerId") != "gelios"
            or provider.get("providerCredential") != {
                "authModeId": "gelios.rest-rotating-bearer.v3",
                "credentialType": "httpBearerAuth",
            }
            or capabilities != [{
                "id": "gelios.monitoring_config.current.read",
                "classification": "read",
                "status": "implemented",
                "request": {
                    "method": "GET",
                    "url": "https://api.geliospro.com/api/v1/users/me/monitoring-config",
                },
                "dataProductIds": ["fleet.positions.current.v3"],
            }, {
                "id": "gelios.units.current.read",
                "classification": "read",
                "status": "implemented",
                "request": {
                    "method": "GET",
                    "url": "https://api.geliospro.com/api/v1/units?incltrip=true",
                },
                "dataProductIds": ["fleet.positions.current.v3"],
            }]
            or provider.get("publisher") != {
                "nodeType": "n8n-nodes-ndc.ndcDataProductPublish",
                "credentialType": "ndcDataProductWriterApi",
            }
        ):
            die("Engine composite provider security catalog projection mismatch")
        provider_catalog = (
            payload_dir / "nodedc-source/server/dataProductPublishGrant/providerCatalog.js"
        ).read_text(encoding="utf-8")
        publish_service = (
            payload_dir / "nodedc-source/server/dataProductPublishGrant/service.js"
        ).read_text(encoding="utf-8")
        publish_store = (
            payload_dir / "nodedc-source/server/dataProductPublishGrant/store.js"
        ).read_text(encoding="utf-8")
        if any(
            marker not in provider_catalog
            for marker in (
                "function capabilityRequests(capability)",
                "function exactHttpRequestUrl(n8n)",
                "capabilityIds",
                "providerRequestNodeIds",
                "providerCredentialRefs.size !== 1",
            )
        ):
            die("Engine composite provider resolver contract mismatch")
        if any(
            marker not in publish_service
            for marker in (
                "capabilities: descriptor.capabilityIds",
                "providerRequestNodeIds: descriptor.providerRequestNodeIds",
            )
        ):
            die("Engine composite provider plan projection mismatch")
        if any(
            marker not in publish_store
            for marker in (
                "Array.isArray(raw.capabilityIds)",
                "Array.isArray(raw.providerRequestNodeIds)",
                "new Set(descriptor.providerRequestNodeIds).size",
            )
        ):
            die("Engine composite provider durable descriptor mismatch")
    validate_no_lifecycle_scripts(payload_dir, "Engine data product publish grant")


def validate_engine_composite_provider_v4_slice(payload_dir, entries):
    if tuple(entries) != ENGINE_COMPOSITE_PROVIDER_V4_ARTIFACT_ENTRIES:
        die("Engine composite provider v4 files.txt exact set/order mismatch")
    for rel, expected_sha256 in ENGINE_COMPOSITE_PROVIDER_V4_TARGET_SHA256.items():
        path = payload_dir / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(f"Engine composite provider v4 target is missing: {rel}")
        if (
            stat.S_ISLNK(path_stat.st_mode)
            or not stat.S_ISREG(path_stat.st_mode)
            or sha256_file(path) != expected_sha256
        ):
            die(f"Engine composite provider v4 target sha256 mismatch: {rel}")

    catalog = read_strict_json(
        payload_dir / ENGINE_PROVIDER_SECURITY_CATALOG_REL,
        "Engine composite provider v4 catalog",
    )
    packages = catalog.get("packages") if isinstance(catalog, dict) else None
    provider = packages[0] if isinstance(packages, list) and len(packages) == 1 else None
    capabilities = provider.get("capabilities") if isinstance(provider, dict) else None
    if (
        catalog.get("schemaVersion") != "nodedc.engine.provider-security-catalog/v1"
        or not isinstance(provider, dict)
        or provider.get("id") != "gelios.provider.v4"
        or provider.get("version") != "4.0.0"
        or provider.get("providerCredential") != {
            "authModeId": "gelios.rest-rotating-bearer.v3",
            "credentialType": "httpBearerAuth",
        }
        or not isinstance(capabilities, list)
        or [item.get("id") for item in capabilities if isinstance(item, dict)] != [
            "gelios.monitoring_config.current.read",
            "gelios.units.current.read",
        ]
        or [item.get("dataProductIds") for item in capabilities if isinstance(item, dict)] != [
            ["fleet.positions.current.v3"],
            ["fleet.positions.current.v3"],
        ]
        or [
            (item.get("request") or {}).get("url")
            for item in capabilities
            if isinstance(item, dict)
        ] != [
            "https://api.geliospro.com/api/v1/users/me/monitoring-config",
            "https://api.geliospro.com/api/v1/units?incltrip=true",
        ]
    ):
        die("Engine composite provider v4 projection mismatch")

    source_markers = {
        "nodedc-source/server/dataProductPublishGrant/providerCatalog.js": (
            "function exactHttpRequestUrl(n8n)",
            "const capabilityIds = productCapabilities.map",
            "providerCredentialRefs.size !== 1",
        ),
        "nodedc-source/server/dataProductPublishGrant/service.js": (
            "capabilities: descriptor.capabilityIds",
            "providerRequestNodeIds: descriptor.providerRequestNodeIds",
        ),
        "nodedc-source/server/dataProductPublishGrant/store.js": (
            "Array.isArray(raw.capabilityIds)",
            "Array.isArray(raw.providerRequestNodeIds)",
        ),
    }
    for rel, markers in source_markers.items():
        source = (payload_dir / rel).read_text(encoding="utf-8")
        if any(marker not in source for marker in markers):
            die(f"Engine composite provider v4 source contract mismatch: {rel}")


def validate_engine_provider_rotating_slot_slice(payload_dir, entries):
    if tuple(entries) != ENGINE_PROVIDER_ROTATING_SLOT_ARTIFACT_ENTRIES:
        die("Engine provider rotating slot files.txt exact set/order mismatch")
    for rel, expected_sha256 in ENGINE_PROVIDER_ROTATING_SLOT_TARGET_SHA256.items():
        path = payload_dir / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(f"Engine provider rotating slot target is missing: {rel}")
        if (
            stat.S_ISLNK(path_stat.st_mode)
            or not stat.S_ISREG(path_stat.st_mode)
            or sha256_file(path) != expected_sha256
        ):
            die(f"Engine provider rotating slot target sha256 mismatch: {rel}")

    catalog = read_strict_json(
        payload_dir / ENGINE_PROVIDER_SECURITY_CATALOG_REL,
        "Engine provider rotating slot catalog",
    )
    packages = catalog.get("packages") if isinstance(catalog, dict) else None
    provider = packages[0] if isinstance(packages, list) and len(packages) == 1 else None
    if (
        not isinstance(provider, dict)
        or provider.get("id") != "gelios.provider.v4"
        or provider.get("providerCredential") != {
            "authModeId": "gelios.rest-rotating-bearer.v3",
            "credentialType": "ndcProviderRotatingAccessApi",
        }
    ):
        die("Engine provider rotating slot catalog projection mismatch")

    resolver = (
        payload_dir / "nodedc-source/server/dataProductPublishGrant/providerCatalog.js"
    ).read_text(encoding="utf-8")
    if (
        "'ndcProviderRotatingAccessApi'" not in resolver
        or "n8n.credentials?.[providerPackage.providerCredential.credentialType]" not in resolver
        or "nodedcAgentCredentialPolicies?.[providerPackage.providerCredential.credentialType]" not in resolver
    ):
        die("Engine provider rotating slot resolver contract mismatch")


def validate_engine_provider_authority_diagnostics_slice(payload_dir, entries):
    if tuple(entries) != ENGINE_PROVIDER_AUTHORITY_DIAGNOSTICS_ARTIFACT_ENTRIES:
        die("Engine provider authority diagnostics files.txt exact set/order mismatch")
    for rel, expected_sha256 in ENGINE_PROVIDER_AUTHORITY_DIAGNOSTICS_TARGET_SHA256.items():
        path = payload_dir / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(f"Engine provider authority diagnostics target is missing: {rel}")
        if (
            stat.S_ISLNK(path_stat.st_mode)
            or not stat.S_ISREG(path_stat.st_mode)
            or sha256_file(path) != expected_sha256
        ):
            die(f"Engine provider authority diagnostics target sha256 mismatch: {rel}")
    source = (
        payload_dir / "nodedc-source/server/nodeIntelligence/upstreamProjection.js"
    ).read_text(encoding="utf-8")
    required_markers = (
        "isUnknownPrivateNodeIssue",
        "issue?.nodeName || issue?.node",
        "privateResults",
        "NDC_PRIVATE_NODE_VALIDATED_BY_ENGINE_CATALOG",
    )
    if any(marker not in source for marker in required_markers):
        die("Engine private node validation reconciliation contract mismatch")
    descriptor = read_engine_node_intelligence_descriptor(
        payload_dir / ENGINE_NODE_INTELLIGENCE_DESCRIPTOR_REL,
        "Engine private node validation reconciliation descriptor",
    )
    if (
        descriptor.get("action") != "activate"
        or descriptor.get("releaseId") != "2.33.2-974a9fb3492f"
        or descriptor.get("source", {}).get("gatewaySha256")
        != "5331f6dc8dc306f641370a2968eb025ee3e278e27ae9a217e4cfc2901fec369c"
        or descriptor.get("source", {}).get("upstreamProjectionSha256")
        != ENGINE_PROVIDER_AUTHORITY_DIAGNOSTICS_TARGET_SHA256[
            "nodedc-source/server/nodeIntelligence/upstreamProjection.js"
        ]
    ):
        die("Engine private node validation reconciliation descriptor mismatch")


def validate_engine_l2_closed_loop_payload(payload_dir, entries):
    if tuple(entries) != ENGINE_L2_CLOSED_LOOP_ARTIFACT_ENTRIES:
        die("Engine L2 closed-loop files.txt exact set/order mismatch")
    actual = collect_exact_files(
        payload_dir,
        entries,
        "Engine L2 closed-loop payload",
    )
    if actual != ENGINE_L2_CLOSED_LOOP_TARGET_SHA256:
        changed = sorted(
            set(actual) ^ set(ENGINE_L2_CLOSED_LOOP_TARGET_SHA256)
            | {
                rel
                for rel in set(actual) & set(ENGINE_L2_CLOSED_LOOP_TARGET_SHA256)
                if actual[rel] != ENGINE_L2_CLOSED_LOOP_TARGET_SHA256[rel]
            }
        )
        detail = changed[0] if changed else "unknown"
        die(f"Engine L2 closed-loop payload digest mismatch: {detail}")

    marker_contract = {
        "nodedc-source/server/l2/graphRepository.js": (
            "expectedRevision",
            "expectedContentRevision",
            "writeAtomic",
            "hydrateWorkflow",
        ),
        ENGINE_NODE_INTELLIGENCE_GATEWAY_REL: (
            "ENGINE_AGENT_MCP_VERSION = '0.7.0'",
            "engine_get_node_output_profile",
            "expectedRevision",
        ),
        "nodedc-source/server/routes/n8n.js": (
            "toSafeNodeOutputProfile",
            "expectedRevision",
            "l2GraphRepository",
        ),
        "nodedc-source/server/routes/ndcAgentMcp.js": (
            "external_codex_mcp",
            "l2GraphRepository",
            "expectedRevision",
        ),
        "nodedc-source/server/realtime/ws.js": (
            "broadcastWorkflowEvent",
        ),
    }
    for rel, markers in marker_contract.items():
        try:
            source = (payload_dir / rel).read_text(encoding="utf-8")
        except (OSError, UnicodeDecodeError):
            die(f"Engine L2 closed-loop source is unreadable: {rel}")
        if any(marker not in source for marker in markers):
            die(f"Engine L2 closed-loop source contract mismatch: {rel}")

    for rel in (
        "nodedc-source/server/l2/graphRepository.js",
        ENGINE_NODE_INTELLIGENCE_GATEWAY_REL,
        "nodedc-source/server/routes/ndcAgentMcp.js",
    ):
        source = (payload_dir / rel).read_text(encoding="utf-8")
        if re.search(r"\b(?:gelios|robot2b)\b", source, re.IGNORECASE):
            die(f"Engine L2 closed-loop provider hardcode is forbidden: {rel}")

    descriptor = read_engine_node_intelligence_descriptor(
        payload_dir / ENGINE_L2_CLOSED_LOOP_DESCRIPTOR_REL,
        "Engine L2 closed-loop node-intelligence descriptor",
    )
    if (
        descriptor.get("action") != "activate"
        or descriptor.get("releaseId") != ENGINE_NODE_INTELLIGENCE_RELEASE_ID
        or descriptor.get("source", {}).get("gatewaySha256")
        != ENGINE_L2_CLOSED_LOOP_TARGET_SHA256[
            ENGINE_NODE_INTELLIGENCE_GATEWAY_REL
        ]
        or descriptor.get("source", {}).get("upstreamProjectionSha256")
        != "2dfa6b4f37d9bfa8b92a8109d4060d02dd2634ceb8f7924504b83ccf3fdd1523"
    ):
        die("Engine L2 closed-loop descriptor target mismatch")
    return descriptor


def validate_engine_depttrans_zone_authority_v1_slice(payload_dir, entries):
    if tuple(entries) != ENGINE_DEPTTRANS_ZONE_AUTHORITY_V1_ARTIFACT_ENTRIES:
        die("Engine Depttrans zone authority v1 files.txt exact set/order mismatch")
    for rel, expected_sha256 in ENGINE_DEPTTRANS_ZONE_AUTHORITY_V1_TARGET_SHA256.items():
        path = payload_dir / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(f"Engine Depttrans zone authority v1 target is missing: {rel}")
        if (
            stat.S_ISLNK(path_stat.st_mode)
            or not stat.S_ISREG(path_stat.st_mode)
            or sha256_file(path) != expected_sha256
        ):
            die(f"Engine Depttrans zone authority v1 target sha256 mismatch: {rel}")

    catalog = read_strict_json(
        payload_dir / ENGINE_PROVIDER_SECURITY_CATALOG_REL,
        "Engine Depttrans zone authority v1 catalog",
    )
    packages = catalog.get("packages") if isinstance(catalog, dict) else None
    package_ids = [item.get("id") for item in packages if isinstance(item, dict)] \
        if isinstance(packages, list) else None
    provider = next(
        (
            item for item in packages
            if isinstance(item, dict)
            and item.get("id") == "moscow-department-of-transport.pmd-slow-zones.v1"
        ),
        None,
    ) if isinstance(packages, list) else None
    capability = provider.get("capabilities", [None])[0] if isinstance(provider, dict) else None
    request = capability.get("request") if isinstance(capability, dict) else None
    marker = read_strict_json(
        payload_dir / "nodedc-source/server/assets/provider-packages/v1/depttrans-zone-authority-v1.json",
        "Engine Depttrans zone authority v1 marker",
    )
    if (
        catalog.get("schemaVersion") != "nodedc.engine.provider-security-catalog/v1"
        or package_ids != [
            "gelios.provider.v1",
            "gelios.provider.v4",
            "gelios.provider.v5",
            "moscow-department-of-transport.pmd-slow-zones.v1",
        ]
        or provider.get("providerId") != "moscow-department-of-transport"
        or provider.get("version") != "1.0.0"
        or "providerCredential" in provider
        or capability.get("id") != "depttrans.pmd-slow-zones.current.read"
        or capability.get("dataProductIds") != ["map.zones.current.v2"]
        or request != {
            "method": "GET",
            "url": "http://map-gateway:18103/internal/zone-sources/v1/profiles/moscow-pmd-slow-zones/current",
            "authorityBoundary": "platform-service",
            "serviceId": "nodedc-map-gateway",
            "network": "engine",
        }
        or marker != {
            "schemaVersion": "nodedc.engine.platform-service-authority/v1",
            "id": "moscow-department-of-transport.pmd-slow-zones.v1",
            "providerId": "moscow-department-of-transport",
            "authorityBoundary": "platform-service",
            "serviceId": "nodedc-map-gateway",
            "network": "engine",
            "dataProductId": "map.zones.current.v2",
        }
    ):
        die("Engine Depttrans zone authority v1 catalog projection mismatch")

    required_markers = {
        "nodedc-source/server/dataProductPublishGrant/providerCatalog.js": (
            "function platformServiceRequestIsExact",
            "authorityBoundary === 'platform-service'",
            "platformServiceIds",
        ),
        "nodedc-source/server/dataProductPublishGrant/service.js": (
            "pinned_platform_service_no_graph_credential",
            "platformServiceIds: descriptor.platformServiceIds",
        ),
        "nodedc-source/server/dataProductPublishGrant/store.js": (
            "new Set(['provider-credential', 'platform-service'])",
            "descriptor.authorityBoundary === 'platform-service'",
        ),
    }
    for rel, markers in required_markers.items():
        source = (payload_dir / rel).read_text(encoding="utf-8")
        if any(marker not in source for marker in markers):
            die(f"Engine Depttrans zone authority v1 source contract mismatch: {rel}")


def validate_engine_provider_target_host_policy_slice(payload_dir, entries):
    if tuple(entries) != ENGINE_PROVIDER_TARGET_HOST_POLICY_ARTIFACT_ENTRIES:
        die("Engine provider target host policy files.txt exact set/order mismatch")
    for rel, expected_sha256 in ENGINE_PROVIDER_TARGET_HOST_POLICY_TARGET_SHA256.items():
        path = payload_dir / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(f"Engine provider target host policy target is missing: {rel}")
        if (
            stat.S_ISLNK(path_stat.st_mode)
            or not stat.S_ISREG(path_stat.st_mode)
            or sha256_file(path) != expected_sha256
        ):
            die(f"Engine provider target host policy target sha256 mismatch: {rel}")
    source = (payload_dir / "nodedc-source/server/routes/n8n.js").read_text(encoding="utf-8")
    required_markers = (
        "const eligibleHosts = explicitHosts.length",
        "allowedHosts: [targetHost]",
        "credential_host_not_allowed",
    )
    if any(marker not in source for marker in required_markers):
        die("Engine provider target host policy contract mismatch")


def validate_engine_mcp_execution_profile_decoder_slice(payload_dir, entries):
    if tuple(entries) != ENGINE_MCP_EXECUTION_PROFILE_DECODER_ARTIFACT_ENTRIES:
        die("Engine MCP execution profile decoder files.txt exact set/order mismatch")
    for rel, expected_sha256 in ENGINE_MCP_EXECUTION_PROFILE_DECODER_TARGET_SHA256.items():
        path = payload_dir / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(f"Engine MCP execution profile decoder target is missing: {rel}")
        if (
            stat.S_ISLNK(path_stat.st_mode)
            or not stat.S_ISREG(path_stat.st_mode)
            or sha256_file(path) != expected_sha256
        ):
            die(f"Engine MCP execution profile decoder target sha256 mismatch: {rel}")
    descriptor = read_strict_json(
        payload_dir / ENGINE_MCP_EXECUTION_PROFILE_DECODER_DESCRIPTOR_REL,
        "Engine MCP execution profile decoder descriptor",
        max_bytes=16 * 1024,
    )
    expected_descriptor = {
        "schemaVersion": "nodedc.engine.deploy-transition/v1",
        "id": "engine-mcp-execution-profile-decoder-v1",
        "component": "engine",
        "scope": "external-mcp-observability",
        "sourcePath": "nodedc-source/server/routes/n8n.js",
        "behavior": "preserve-top-level-numeric-string-primitives-in-flatted-execution-data",
        "acceptance": {
            "tool": "engine_get_node_output_profile",
            "valuesIncluded": False,
            "rawExecutionDataIncluded": False,
        },
    }
    if descriptor != expected_descriptor:
        die("Engine MCP execution profile decoder descriptor contract mismatch")
    source = (payload_dir / "nodedc-source/server/routes/n8n.js").read_text(
        encoding="utf-8"
    )
    required_markers = (
        "const compactReference = Symbol('n8nCompactReference')",
        "Top-level string entries are primitive values.",
        "valuesIncluded: false,",
    )
    if any(marker not in source for marker in required_markers):
        die("Engine MCP execution profile decoder source contract mismatch")


def validate_engine_mcp_telemetry_catalog_slice(payload_dir, entries):
    if tuple(entries) != ENGINE_MCP_TELEMETRY_CATALOG_ARTIFACT_ENTRIES:
        die("Engine MCP telemetry catalog files.txt exact set/order mismatch")
    for rel, expected_sha256 in ENGINE_MCP_TELEMETRY_CATALOG_TARGET_SHA256.items():
        path = payload_dir / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(f"Engine MCP telemetry catalog target is missing: {rel}")
        if (
            stat.S_ISLNK(path_stat.st_mode)
            or not stat.S_ISREG(path_stat.st_mode)
            or sha256_file(path) != expected_sha256
        ):
            die(f"Engine MCP telemetry catalog target sha256 mismatch: {rel}")
    descriptor = read_strict_json(
        payload_dir / ENGINE_MCP_TELEMETRY_CATALOG_DESCRIPTOR_REL,
        "Engine MCP telemetry catalog descriptor",
        max_bytes=16 * 1024,
    )
    expected_descriptor = {
        "schemaVersion": "nodedc.engine.deploy-transition/v1",
        "id": "engine-mcp-telemetry-reading-catalog-v1",
        "component": "engine",
        "scope": "external-mcp-observability",
        "mcpVersion": "0.8.0",
        "sourcePaths": [
            "nodedc-source/server/routes/n8n.js",
            "nodedc-source/server/routes/engineAgentGateway.js",
        ],
        "readsOnly": "normalized-attributes.sensor_readings",
        "returns": [
            "reading-id",
            "safe-label",
            "safe-unit",
            "value-types",
            "coverage-counts",
        ],
        "neverReturns": [
            "reading-value",
            "raw-execution-data",
            "raw-provider-payload",
            "credential-shaped-data",
        ],
    }
    if descriptor != expected_descriptor:
        die("Engine MCP telemetry catalog descriptor contract mismatch")
    n8n_source = (payload_dir / "nodedc-source/server/routes/n8n.js").read_text(
        encoding="utf-8"
    )
    gateway_source = (
        payload_dir / "nodedc-source/server/routes/engineAgentGateway.js"
    ).read_text(encoding="utf-8")
    if any(
        marker not in n8n_source
        for marker in (
            "function toSafeTelemetryReadingCatalog",
            "key === 'sensor_readings' && pathName.endsWith('.attributes')",
            "valuesIncluded: false,",
            "rawExecutionDataIncluded: false,",
        )
    ):
        die("Engine MCP telemetry catalog backend contract mismatch")
    if any(
        marker not in gateway_source
        for marker in (
            "const ENGINE_AGENT_MCP_VERSION = '0.8.0'",
            "name: 'engine_get_telemetry_reading_catalog'",
            "/telemetry-reading-catalog?",
        )
    ):
        die("Engine MCP telemetry catalog gateway contract mismatch")
    node_intelligence_descriptor = read_engine_node_intelligence_descriptor(
        payload_dir / ENGINE_NODE_INTELLIGENCE_DESCRIPTOR_REL,
        "Engine MCP telemetry catalog node-intelligence descriptor",
    )
    if (
        node_intelligence_descriptor.get("action") != "activate"
        or node_intelligence_descriptor.get("releaseId")
        != ENGINE_NODE_INTELLIGENCE_RELEASE_ID
        or node_intelligence_descriptor.get("source", {}).get("gatewaySha256")
        != ENGINE_MCP_TELEMETRY_CATALOG_TARGET_SHA256[
            ENGINE_NODE_INTELLIGENCE_GATEWAY_REL
        ]
    ):
        die(
            "Engine MCP telemetry catalog node-intelligence attestation "
            "contract mismatch"
        )


def validate_engine_mcp_execution_plan_materialization_slice(payload_dir, entries):
    if tuple(entries) != ENGINE_MCP_EXECUTION_PLAN_MATERIALIZATION_ARTIFACT_ENTRIES:
        die(
            "Engine MCP execution plan materialization files.txt exact "
            "set/order mismatch"
        )
    for rel, expected_sha256 in (
        ENGINE_MCP_EXECUTION_PLAN_MATERIALIZATION_TARGET_SHA256.items()
    ):
        path = payload_dir / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(f"Engine MCP execution plan materialization target is missing: {rel}")
        if (
            stat.S_ISLNK(path_stat.st_mode)
            or not stat.S_ISREG(path_stat.st_mode)
            or sha256_file(path) != expected_sha256
        ):
            die(
                "Engine MCP execution plan materialization target sha256 "
                f"mismatch: {rel}"
            )
    descriptor = read_strict_json(
        payload_dir / ENGINE_MCP_EXECUTION_PLAN_MATERIALIZATION_DESCRIPTOR_REL,
        "Engine MCP execution plan materialization descriptor",
        max_bytes=32 * 1024,
    )
    expected_descriptor = {
        "schemaVersion": "nodedc.engine.deploy-transition/v1",
        "id": "engine-mcp-l2-execution-plan-materialization-v1",
        "component": "engine",
        "scope": "external-mcp-l2-authoring",
        "mcpVersion": "0.9.0",
        "sourcePaths": [
            "nodedc-source/server/routes/n8n.js",
            "nodedc-source/server/routes/engineAgentGateway.js",
            "nodedc-source/server/l2ExecutionPlan/catalog.js",
            "nodedc-source/server/l2ExecutionPlan/compiler.js",
            "nodedc-source/server/l2ExecutionPlan/materializer.js",
            "nodedc-source/server/assets/execution-plans/v1/catalog.json",
        ],
        "plan": {
            "tool": "engine_plan_l2_execution_plan_materialization",
            "readOnly": True,
            "returnsPlanRef": True,
        },
        "apply": {
            "tool": "engine_apply_l2_execution_plan_materialization",
            "accepts": [
                "planRef",
                "providerAuthRef",
                "confirmation",
                "changeRef",
            ],
            "rejectsCallerGraphOperations": True,
            "revalidatesTargetRevisionAndScope": True,
        },
        "providerLogicAuthority": "trusted-provider-package",
        "unmanagedGraphPolicy": "explicit-adoption-required",
        "embeddedCodexChanged": False,
    }
    if descriptor != expected_descriptor:
        die("Engine MCP execution plan materialization descriptor contract mismatch")
    gateway_source = (
        payload_dir / "nodedc-source/server/routes/engineAgentGateway.js"
    ).read_text(encoding="utf-8")
    if any(
        marker not in gateway_source
        for marker in (
            "const ENGINE_AGENT_MCP_VERSION = '0.9.0'",
            "name: 'engine_plan_l2_execution_plan_materialization'",
            "name: 'engine_apply_l2_execution_plan_materialization'",
            "'execution-plan.apply'",
            "assertExactToolArguments(args, [",
        )
    ):
        die("Engine MCP execution plan materialization gateway contract mismatch")
    materializer_source = (
        payload_dir / "nodedc-source/server/l2ExecutionPlan/materializer.js"
    ).read_text(encoding="utf-8")
    compiler_source = (
        payload_dir / "nodedc-source/server/l2ExecutionPlan/compiler.js"
    ).read_text(encoding="utf-8")
    if any(
        marker not in materializer_source
        for marker in (
            "status: 'adoption_required'",
            "type: 'replaceGraph'",
            "assignCredentialBindingInternal",
            "execution_plan_materialization_equality_failed",
        )
    ):
        die("Engine MCP execution plan materializer contract mismatch")
    if any(
        marker not in compiler_source
        for marker in (
            "compileExecutionPlanGraph",
            "materializedGraphEqualityDigest",
            "ndc.semantic-mapping",
            "providerPackage.publisher.nodeType",
        )
    ):
        die("Engine MCP execution plan compiler contract mismatch")
    if re.search(r"gelios|robot2b", materializer_source, re.IGNORECASE) or re.search(
        r"gelios|robot2b",
        compiler_source,
        re.IGNORECASE,
    ):
        die("Engine MCP execution plan runtime contains provider hardcode")
    node_intelligence_descriptor = read_engine_node_intelligence_descriptor(
        payload_dir / ENGINE_NODE_INTELLIGENCE_DESCRIPTOR_REL,
        "Engine MCP execution plan materialization node-intelligence descriptor",
    )
    if (
        node_intelligence_descriptor.get("action") != "activate"
        or node_intelligence_descriptor.get("releaseId")
        != ENGINE_NODE_INTELLIGENCE_RELEASE_ID
        or node_intelligence_descriptor.get("source", {}).get("gatewaySha256")
        != ENGINE_MCP_EXECUTION_PLAN_MATERIALIZATION_TARGET_SHA256[
            ENGINE_NODE_INTELLIGENCE_GATEWAY_REL
        ]
    ):
        die(
            "Engine MCP execution plan materialization node-intelligence "
            "attestation contract mismatch"
        )


def validate_engine_mcp_execution_plan_telemetry_runtime_slice(
    payload_dir,
    entries,
):
    if (
        tuple(entries)
        != ENGINE_MCP_EXECUTION_PLAN_TELEMETRY_RUNTIME_ARTIFACT_ENTRIES
    ):
        die(
            "Engine MCP execution plan telemetry runtime files.txt exact "
            "set/order mismatch"
        )
    for rel, expected_sha256 in (
        ENGINE_MCP_EXECUTION_PLAN_TELEMETRY_RUNTIME_TARGET_SHA256.items()
    ):
        path = payload_dir / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(
                "Engine MCP execution plan telemetry runtime target is "
                f"missing: {rel}"
            )
        if (
            stat.S_ISLNK(path_stat.st_mode)
            or not stat.S_ISREG(path_stat.st_mode)
            or sha256_file(path) != expected_sha256
        ):
            die(
                "Engine MCP execution plan telemetry runtime target sha256 "
                f"mismatch: {rel}"
            )
    descriptor = read_strict_json(
        payload_dir
        / ENGINE_MCP_EXECUTION_PLAN_TELEMETRY_RUNTIME_DESCRIPTOR_REL,
        "Engine MCP execution plan telemetry runtime descriptor",
        max_bytes=32 * 1024,
    )
    expected_descriptor = {
        "schemaVersion": "nodedc.engine.deploy-transition/v1",
        "id": "engine-mcp-l2-execution-plan-telemetry-runtime-v2",
        "component": "engine",
        "scope": "external-mcp-l2-authoring-runtime",
        "mcpVersion": "0.9.0",
        "sourcePaths": [
            "nodedc-source/server/l2ExecutionPlan/compiler.js",
            "nodedc-source/server/assets/execution-plans/v1/catalog.json",
        ],
        "compilerTransition": {
            "predecessor": "1.1.0",
            "supported": ["1.1.0", "1.2.0"],
            "legacyRuntimePreserved": True,
        },
        "telemetryInputBoundary": {
            "sources": [
                "declared-sensor-values",
                "declared-message-parameters",
            ],
            "authorization": [
                "trusted-telemetry-projection",
                "visible-sensor-definition",
            ],
            "unprojectedParameters": "discarded",
            "rawProviderPayloadAtPublish": "forbidden",
            "conversion": "bounded-declared-conversion-table",
        },
        "providerLogicAuthority": "trusted-provider-package",
        "engineProviderHardcode": False,
        "embeddedCodexChanged": False,
    }
    if descriptor != expected_descriptor:
        die(
            "Engine MCP execution plan telemetry runtime descriptor "
            "contract mismatch"
        )
    compiler_source = (
        payload_dir / "nodedc-source/server/l2ExecutionPlan/compiler.js"
    ).read_text(encoding="utf-8")
    catalog = read_strict_json(
        payload_dir
        / "nodedc-source/server/assets/execution-plans/v1/catalog.json",
        "Engine execution plan catalog",
        max_bytes=512 * 1024,
    )
    required_markers = (
        "if (compilerVersion === '1.1.0')",
        "if (compilerVersion !== '1.2.0')",
        '"msgParam", "msg_param"',
        "descriptor.telemetryProjection",
        '"message-param"',
        "convertedSensorValue",
        "visibleSensorDefinition",
    )
    if any(marker not in compiler_source for marker in required_markers):
        die("Engine MCP execution plan telemetry runtime contract mismatch")
    if catalog.get("runtime", {}).get("compilerVersions") != ["1.1.0", "1.2.0"]:
        die("Engine MCP execution plan telemetry runtime catalog mismatch")
    if re.search(r"gelios|robot2b", compiler_source, re.IGNORECASE):
        die("Engine MCP execution plan telemetry runtime contains provider hardcode")


def validate_engine_mcp_execution_plan_module_ownership_slice(
    payload_dir,
    entries,
):
    if (
        tuple(entries)
        != ENGINE_MCP_EXECUTION_PLAN_MODULE_OWNERSHIP_ARTIFACT_ENTRIES
    ):
        die(
            "Engine MCP execution plan module ownership files.txt exact "
            "set/order mismatch"
        )
    for rel, expected_sha256 in (
        ENGINE_MCP_EXECUTION_PLAN_MODULE_OWNERSHIP_TARGET_SHA256.items()
    ):
        path = payload_dir / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(
                "Engine MCP execution plan module ownership target is "
                f"missing: {rel}"
            )
        if (
            stat.S_ISLNK(path_stat.st_mode)
            or not stat.S_ISREG(path_stat.st_mode)
            or sha256_file(path) != expected_sha256
        ):
            die(
                "Engine MCP execution plan module ownership target sha256 "
                f"mismatch: {rel}"
            )
    descriptor = read_strict_json(
        payload_dir
        / ENGINE_MCP_EXECUTION_PLAN_MODULE_OWNERSHIP_DESCRIPTOR_REL,
        "Engine MCP execution plan module ownership descriptor",
        max_bytes=32 * 1024,
    )
    expected_descriptor = {
        "schemaVersion": "nodedc.engine.deploy-transition/v1",
        "id": "engine-mcp-l2-execution-plan-module-ownership-v3",
        "component": "engine",
        "scope": "external-mcp-l2-authoring-runtime",
        "mcpVersion": "0.10.0",
        "sourcePaths": [
            "nodedc-source/server/l2ExecutionPlan/materializer.js",
            "nodedc-source/server/routes/engineAgentGateway.js",
            "nodedc-source/server/assets/execution-plans/v1/catalog.json",
        ],
        "moduleOwnership": {
            "schemaVersion":
                "nodedc.engine.materialized-execution-plan-module/v1",
            "adoptionStrategy": "adopt_existing_module",
            "reconciliationStrategy": "create_or_reconcile_owned",
            "nodeBindings": "exact-one-to-one",
            "retirementScope": "closed-module-boundary",
            "unrelatedNodes": "preserved",
            "unrelatedEdges": "preserved",
            "internalEdges": "server-derived-from-trusted-plan",
            "wholeGraphReplacement": "not-required",
        },
        "sharedBoundary": {
            "runtimeKinds": ["ndc.manual-trigger"],
            "nodeTypes": ["n8n-nodes-base.webhook"],
            "compatibility": "same-node-type-and-http-method",
            "configurationAuthority": "existing-graph",
            "providerCredentialNodes": "must-be-engine-managed",
            "publisherNodes": "must-be-engine-managed",
        },
        "providerPackageTrust": {
            "addedPackageId": "gelios.provider.v9",
            "addedPackageDigest":
                "sha256:7dd4ce4a45ce76e884ffa1e304bfaa521f552e9a45e535930f2d17b882ae23ed",
            "legacyPackageId": "gelios.provider.v8",
            "legacyPackagePreserved": True,
            "telemetryRegistryDigest":
                "sha256:8338dd1f3e757dae5a0fc558e41b3a5cc6395c33c94841ce4d2af976e1911381",
            "telemetryProjectionDigest":
                "sha256:ecdafb13173338f10043a08603ddd5cd1f6091f1c54d7fbb7e8a9606fbbdef65",
            "providerLogicAuthority": "trusted-provider-package",
        },
        "engineProviderHardcode": False,
        "embeddedCodexChanged": False,
    }
    if descriptor != expected_descriptor:
        die(
            "Engine MCP execution plan module ownership descriptor "
            "contract mismatch"
        )
    materializer_source = (
        payload_dir / "nodedc-source/server/l2ExecutionPlan/materializer.js"
    ).read_text(encoding="utf-8")
    gateway_source = (
        payload_dir / "nodedc-source/server/routes/engineAgentGateway.js"
    ).read_text(encoding="utf-8")
    for marker in (
        "nodedc.engine.materialized-execution-plan-module/v1",
        "adopt_existing_module",
        "preserveBoundNodeIds",
        "execution_plan_module_retire_boundary_not_closed",
        "manual_webhook_same_method",
    ):
        if marker not in materializer_source:
            die(
                "Engine MCP execution plan module ownership contract "
                f"marker missing: {marker}"
            )
    if (
        "const ENGINE_AGENT_MCP_VERSION = '0.10.0'" not in gateway_source
        or "preserveBoundNodeIds" not in gateway_source
        or "adopt_existing_module" not in gateway_source
    ):
        die("Engine MCP execution plan module ownership gateway mismatch")
    if re.search(r"gelios|robot2b", materializer_source, re.IGNORECASE):
        die("Engine MCP execution plan module ownership contains provider hardcode")
    catalog = read_strict_json(
        payload_dir
        / "nodedc-source/server/assets/execution-plans/v1/catalog.json",
        "Engine execution plan catalog",
        max_bytes=512 * 1024,
    )
    package_by_id = {
        package.get("id"): package
        for package in catalog.get("packages", [])
        if isinstance(package, dict)
    }
    if (
        package_by_id.get("gelios.provider.v9", {}).get("contractDigest")
        != "sha256:7dd4ce4a45ce76e884ffa1e304bfaa521f552e9a45e535930f2d17b882ae23ed"
        or "gelios.provider.v8" not in package_by_id
    ):
        die("Engine MCP execution plan module ownership catalog mismatch")
    node_intelligence_descriptor = read_engine_node_intelligence_descriptor(
        payload_dir / ENGINE_NODE_INTELLIGENCE_DESCRIPTOR_REL,
        "Engine MCP execution plan module ownership node-intelligence descriptor",
    )
    if (
        node_intelligence_descriptor.get("action") != "activate"
        or node_intelligence_descriptor.get("releaseId")
        != ENGINE_NODE_INTELLIGENCE_RELEASE_ID
        or node_intelligence_descriptor.get("source", {}).get("gatewaySha256")
        != ENGINE_MCP_EXECUTION_PLAN_MODULE_OWNERSHIP_TARGET_SHA256[
            ENGINE_NODE_INTELLIGENCE_GATEWAY_REL
        ]
    ):
        die(
            "Engine MCP execution plan module ownership node-intelligence "
            "attestation contract mismatch"
        )


def validate_engine_mcp_normalized_identity_search_slice(payload_dir, entries):
    if tuple(entries) != ENGINE_MCP_NORMALIZED_IDENTITY_SEARCH_ARTIFACT_ENTRIES:
        die(
            "Engine MCP normalized identity search files.txt exact set/order "
            "mismatch"
        )
    for rel, expected_sha256 in (
        ENGINE_MCP_NORMALIZED_IDENTITY_SEARCH_TARGET_SHA256.items()
    ):
        path = payload_dir / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(f"Engine MCP normalized identity search target is missing: {rel}")
        if (
            stat.S_ISLNK(path_stat.st_mode)
            or not stat.S_ISREG(path_stat.st_mode)
            or sha256_file(path) != expected_sha256
        ):
            die(
                "Engine MCP normalized identity search target sha256 mismatch: "
                f"{rel}"
            )

    descriptor = read_strict_json(
        payload_dir / ENGINE_MCP_NORMALIZED_IDENTITY_SEARCH_DESCRIPTOR_REL,
        "Engine MCP normalized identity search descriptor",
        max_bytes=32 * 1024,
    )
    expected_descriptor = {
        "schemaVersion": "nodedc.engine.deploy-transition/v1",
        "id": "engine-mcp-normalized-identity-search-v1",
        "component": "engine",
        "scope": "external-mcp-readonly-identity-discovery",
        "mcpVersion": "0.11.0",
        "sourcePaths": [
            "nodedc-source/server/routes/n8n.js",
            "nodedc-source/server/routes/engineAgentGateway.js",
            "nodedc-source/server/l2ExecutionPlan/compiler.js",
            "nodedc-source/server/assets/execution-plans/v1/catalog.json",
            "nodedc-source/server/assets/provider-packages/v1/catalog.json",
        ],
        "normalizedFactSearch": {
            "tool": "engine_find_normalized_subjects",
            "authority": "granted-execution-normalized-facts",
            "matchModes": ["exact", "prefix", "contains"],
            "queryScopes": ["canonical-fields", "point-bounding-box"],
            "fullAdministrativeIdentifiers": True,
            "rawExecutionData": False,
            "rawProviderPayload": False,
            "commandSurface": False,
        },
        "executionPlanRuntime": {
            "compilerVersionAdded": "1.4.0",
            "legacyCompilerVersionsPreserved": ["1.1.0", "1.2.0", "1.3.0"],
            "derivationKindsAdded": [
                "bounded_string_list",
                "bounded_named_values",
            ],
            "providerSpecificLogicInEngine": False,
        },
        "providerPackageTrust": {
            "addedPackageId": "gelios.provider.v11",
            "addedPackageDigest":
                "sha256:4bf211d9ed6cfd227df444d49d8c5ce77a24389ed2ba3d159d53d83e0d4738d9",
            "identityCapabilityId": "gelios.units.identity.read",
            "identityDataProductId": "fleet.units.identity.current.v1",
            "legacyPackagesPreserved": True,
        },
        "reverseGeocodingChanged": False,
        "embeddedCodexChanged": False,
    }
    if descriptor != expected_descriptor:
        die("Engine MCP normalized identity search descriptor contract mismatch")

    gateway_source = (
        payload_dir / ENGINE_NODE_INTELLIGENCE_GATEWAY_REL
    ).read_text(encoding="utf-8")
    route_source = (
        payload_dir / "nodedc-source/server/routes/n8n.js"
    ).read_text(encoding="utf-8")
    compiler_source = (
        payload_dir / "nodedc-source/server/l2ExecutionPlan/compiler.js"
    ).read_text(encoding="utf-8")
    for marker in (
        "engine_find_normalized_subjects",
        "const ENGINE_AGENT_MCP_VERSION = '0.11.0'",
    ):
        if marker not in gateway_source:
            die(
                "Engine MCP normalized identity search gateway marker missing: "
                f"{marker}"
            )
    for marker in (
        "normalized-fact-search",
        "normalizedFactsOnly: true",
        "rawExecutionDataIncluded: false",
        "commandSurfaceIncluded: false",
    ):
        if marker not in route_source:
            die(
                "Engine MCP normalized identity search route marker missing: "
                f"{marker}"
            )
    for marker in ("boundedStringList", "boundedNamedValues", "'1.4.0'"):
        if marker not in compiler_source:
            die(
                "Engine MCP normalized identity search compiler marker missing: "
                f"{marker}"
            )
    if re.search(r"gelios|robot2b", compiler_source, re.IGNORECASE):
        die("Engine MCP normalized identity search contains provider hardcode")

    execution_catalog = read_strict_json(
        payload_dir
        / "nodedc-source/server/assets/execution-plans/v1/catalog.json",
        "Engine execution plan catalog",
        max_bytes=1024 * 1024,
    )
    package_by_id = {
        package.get("id"): package
        for package in execution_catalog.get("packages", [])
        if isinstance(package, dict)
    }
    gelios_v11 = package_by_id.get("gelios.provider.v11", {})
    if (
        execution_catalog.get("runtime", {}).get("compilerVersions")
        != ["1.1.0", "1.2.0", "1.3.0", "1.4.0"]
        or gelios_v11.get("contractDigest")
        != "sha256:4bf211d9ed6cfd227df444d49d8c5ce77a24389ed2ba3d159d53d83e0d4738d9"
        or not any(
            profile.get("dataProductId") == "fleet.units.identity.current.v1"
            for profile in gelios_v11.get("profiles", [])
            if isinstance(profile, dict)
        )
    ):
        die("Engine MCP normalized identity search execution catalog mismatch")

    security_catalog = read_strict_json(
        payload_dir
        / "nodedc-source/server/assets/provider-packages/v1/catalog.json",
        "Engine provider security catalog",
        max_bytes=512 * 1024,
    )
    security_package = next(
        (
            package
            for package in security_catalog.get("packages", [])
            if isinstance(package, dict)
            and package.get("id") == "gelios.provider.v11"
        ),
        {},
    )
    capabilities = security_package.get("capabilities", [])
    if (
        len(capabilities) != 1
        or capabilities[0].get("id") != "gelios.units.identity.read"
        or capabilities[0].get("classification") != "read"
        or capabilities[0].get("dataProductIds")
        != ["fleet.units.identity.current.v1"]
    ):
        die("Engine MCP normalized identity search security catalog mismatch")

    node_intelligence_descriptor = read_engine_node_intelligence_descriptor(
        payload_dir / ENGINE_NODE_INTELLIGENCE_DESCRIPTOR_REL,
        "Engine MCP normalized identity search node-intelligence descriptor",
    )
    if (
        node_intelligence_descriptor.get("action") != "activate"
        or node_intelligence_descriptor.get("releaseId")
        != ENGINE_NODE_INTELLIGENCE_RELEASE_ID
        or node_intelligence_descriptor.get("source", {}).get("gatewaySha256")
        != ENGINE_MCP_NORMALIZED_IDENTITY_SEARCH_TARGET_SHA256[
            ENGINE_NODE_INTELLIGENCE_GATEWAY_REL
        ]
    ):
        die(
            "Engine MCP normalized identity search node-intelligence "
            "attestation contract mismatch"
        )


def validate_engine_mcp_l1_credential_reuse_slice(payload_dir, entries):
    if tuple(entries) != ENGINE_MCP_L1_CREDENTIAL_REUSE_ARTIFACT_ENTRIES:
        die(
            "Engine MCP L1 credential reuse files.txt exact set/order "
            "mismatch"
        )
    for rel, expected_sha256 in (
        ENGINE_MCP_L1_CREDENTIAL_REUSE_TARGET_SHA256.items()
    ):
        path = payload_dir / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(f"Engine MCP L1 credential reuse target is missing: {rel}")
        if (
            stat.S_ISLNK(path_stat.st_mode)
            or not stat.S_ISREG(path_stat.st_mode)
            or sha256_file(path) != expected_sha256
        ):
            die(
                "Engine MCP L1 credential reuse target sha256 mismatch: "
                f"{rel}"
            )

    descriptor = read_strict_json(
        payload_dir / ENGINE_MCP_L1_CREDENTIAL_REUSE_DESCRIPTOR_REL,
        "Engine MCP L1 credential reuse descriptor",
        max_bytes=32 * 1024,
    )
    expected_descriptor = {
        "schemaVersion": "nodedc.engine.deploy-transition/v1",
        "id": "engine-mcp-l1-credential-reuse-v1",
        "component": "engine",
        "scope": "external-mcp-l2-authoring",
        "mcpVersion": "0.11.0",
        "sourcePath": "nodedc-source/server/routes/n8n.js",
        "visibilityProof": {
            "scope": "same-l1-workflow",
            "source": "local-registry-provenance",
            "instanceScope": "preserved",
        },
        "binding": {
            "listTool": "engine_list_l2_credential_refs",
            "applyOperation": "assignCredentialRef",
            "returns": ["label", "status", "scope", "opaque-ref"],
            "neverReturns": [
                "native-credential-id",
                "logical-credential-id",
                "credential-data",
                "credential-value",
            ],
        },
        "transportPolicy": {
            "httpsRequired": True,
            "redirectsDisabled": True,
            "hostAuthority": [
                "credential-allowlist",
                "same-l1-observed-host",
            ],
        },
        "managedGrants": "target-local",
        "crossL1Sharing": False,
    }
    if descriptor != expected_descriptor:
        die("Engine MCP L1 credential reuse descriptor contract mismatch")

    route_source = (
        payload_dir / "nodedc-source/server/routes/n8n.js"
    ).read_text(encoding="utf-8")
    for marker in (
        "function engineAgentCredentialMayReuseWithinL1",
        "function buildEngineAgentL1CredentialContext",
        "return 'l1'",
        "candidateScope === 'l1' ? l1Context.graph : graph",
        "managed writer/reader grants",
    ):
        if marker not in route_source:
            die(
                "Engine MCP L1 credential reuse route marker missing: "
                f"{marker}"
            )
    if (
        "LEGACY_CREDENTIAL_SINK_OWNER" not in route_source
        or "DATA_PRODUCT_PUBLISH_GRANT_OWNER" not in route_source
        or "DATA_PRODUCT_READ_GRANT_OWNER" not in route_source
    ):
        die("Engine MCP L1 credential reuse managed-grant boundary missing")


def validate_engine_mcp_l1_credential_provenance_slice(payload_dir, entries):
    if tuple(entries) != ENGINE_MCP_L1_CREDENTIAL_PROVENANCE_ARTIFACT_ENTRIES:
        die(
            "Engine MCP L1 credential provenance files.txt exact set/order "
            "mismatch"
        )
    for rel, expected_sha256 in (
        ENGINE_MCP_L1_CREDENTIAL_PROVENANCE_TARGET_SHA256.items()
    ):
        path = payload_dir / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(f"Engine MCP L1 credential provenance target is missing: {rel}")
        if (
            stat.S_ISLNK(path_stat.st_mode)
            or not stat.S_ISREG(path_stat.st_mode)
            or sha256_file(path) != expected_sha256
        ):
            die(
                "Engine MCP L1 credential provenance target sha256 mismatch: "
                f"{rel}"
            )

    descriptor = read_strict_json(
        payload_dir / ENGINE_MCP_L1_CREDENTIAL_PROVENANCE_DESCRIPTOR_REL,
        "Engine MCP L1 credential provenance descriptor",
        max_bytes=32 * 1024,
    )
    expected_descriptor = {
        "schemaVersion": "nodedc.engine.deploy-transition/v1",
        "id": "engine-mcp-l1-credential-provenance-v2",
        "component": "engine",
        "scope": "external-mcp-l2-authoring",
        "mcpVersion": "0.11.0",
        "sourcePath": "nodedc-source/server/routes/n8n.js",
        "predecessor": "engine-mcp-l1-credential-reuse-v1",
        "visibilityProof": {
            "scope": "same-l1-workflow",
            "localSources": ["manual", "workflow-ref", "credentials-file"],
            "referencedSourceRequiresSyncPayload": True,
            "logicalKeyEqualityRequired": True,
        },
        "candidateBoundary": {
            "commonEntryMustBeReusable": True,
            "managedEntriesAllowed": False,
            "managedGrants": "target-local",
        },
        "binding": {
            "listTool": "engine_list_l2_credential_refs",
            "applyOperation": "assignCredentialRef",
            "opaqueRefOnly": True,
            "credentialIdsReturned": False,
            "credentialValuesReturned": False,
        },
        "transportPolicy": {
            "httpsRequired": True,
            "redirectsDisabled": True,
            "hostAuthority": [
                "credential-allowlist",
                "same-l1-observed-host",
            ],
        },
        "crossL1Sharing": False,
    }
    if descriptor != expected_descriptor:
        die("Engine MCP L1 credential provenance descriptor contract mismatch")

    route_source = (
        payload_dir / "nodedc-source/server/routes/n8n.js"
    ).read_text(encoding="utf-8")
    for marker in (
        "function engineAgentCredentialMayProveL1Provenance",
        "return isGlobalRegistryEntryAllowed(entry)",
        "engineAgentCredentialMayProveL1Provenance(item)",
        "The common candidate itself is",
    ):
        if marker not in route_source:
            die(
                "Engine MCP L1 credential provenance route marker missing: "
                f"{marker}"
            )


def validate_engine_mcp_execution_plan_sandbox_runtime_slice(
    payload_dir,
    entries,
):
    if (
        tuple(entries)
        != ENGINE_MCP_EXECUTION_PLAN_SANDBOX_RUNTIME_ARTIFACT_ENTRIES
    ):
        die(
            "Engine MCP execution plan sandbox runtime files.txt exact "
            "set/order mismatch"
        )
    for rel, expected_sha256 in (
        ENGINE_MCP_EXECUTION_PLAN_SANDBOX_RUNTIME_TARGET_SHA256.items()
    ):
        path = payload_dir / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(
                "Engine MCP execution plan sandbox runtime target is "
                f"missing: {rel}"
            )
        if (
            stat.S_ISLNK(path_stat.st_mode)
            or not stat.S_ISREG(path_stat.st_mode)
            or sha256_file(path) != expected_sha256
        ):
            die(
                "Engine MCP execution plan sandbox runtime target sha256 "
                f"mismatch: {rel}"
            )

    descriptor = read_strict_json(
        payload_dir / ENGINE_MCP_EXECUTION_PLAN_SANDBOX_RUNTIME_DESCRIPTOR_REL,
        "Engine MCP execution plan sandbox runtime descriptor",
        max_bytes=32 * 1024,
    )
    expected_descriptor = {
        "schemaVersion": "nodedc.engine.deploy-transition/v1",
        "id": "engine-mcp-l2-execution-plan-sandbox-runtime-v4",
        "component": "engine",
        "scope": "external-mcp-l2-authoring-runtime",
        "mcpVersion": "0.11.0",
        "sourcePath": "nodedc-source/server/l2ExecutionPlan/compiler.js",
        "predecessor": "engine-mcp-l1-credential-provenance-v2",
        "runtimeCompatibility": {
            "n8nVersion": "2.3.2",
            "codeNodeMode": "runOnceForAllItems",
            "sandboxGlobalDependencies": [],
            "responseByteBudget": "bounded-pure-javascript-utf8",
            "returnedItems": "n8n-object-json-envelope",
        },
        "dataBoundary": {
            "providerResponses": "bounded-by-trusted-profile",
            "rawProviderPayloadAtPublish": "forbidden",
            "canonicalFactsOnlyAtPublish": True,
        },
        "providerLogicAuthority": "trusted-provider-package",
        "engineProviderHardcode": False,
        "n8nCoreChanged": False,
        "l1Changed": False,
        "credentialsChanged": False,
    }
    if descriptor != expected_descriptor:
        die("Engine MCP execution plan sandbox runtime descriptor mismatch")

    compiler = (
        payload_dir / "nodedc-source/server/l2ExecutionPlan/compiler.js"
    ).read_text(encoding="utf-8")
    for marker in (
        "const encodedBytes = (value) => {",
        "encoded.charCodeAt(index)",
        "length += 4",
        "return extracted.map((source) => ({ json:",
    ):
        if marker not in compiler:
            die(
                "Engine MCP execution plan sandbox runtime compiler marker "
                f"missing: {marker}"
            )
    if (
        "new TextEncoder().encode(JSON.stringify(value ?? null))" in compiler
        or re.search(r"gelios|robot2b", compiler, re.IGNORECASE)
    ):
        die(
            "Engine MCP execution plan sandbox runtime provider-neutral "
            "boundary mismatch"
        )


def validate_engine_mcp_gelios_items_envelope_slice(payload_dir, entries):
    if tuple(entries) != ENGINE_MCP_GELIOS_ITEMS_ENVELOPE_ARTIFACT_ENTRIES:
        die(
            "Engine MCP Gelios items envelope files.txt exact set/order "
            "mismatch"
        )
    for rel, expected_sha256 in (
        ENGINE_MCP_GELIOS_ITEMS_ENVELOPE_TARGET_SHA256.items()
    ):
        path = payload_dir / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(f"Engine MCP Gelios items envelope target is missing: {rel}")
        if (
            stat.S_ISLNK(path_stat.st_mode)
            or not stat.S_ISREG(path_stat.st_mode)
            or sha256_file(path) != expected_sha256
        ):
            die(
                "Engine MCP Gelios items envelope target sha256 mismatch: "
                f"{rel}"
            )

    descriptor = read_strict_json(
        payload_dir / ENGINE_MCP_GELIOS_ITEMS_ENVELOPE_DESCRIPTOR_REL,
        "Engine MCP Gelios items envelope descriptor",
        max_bytes=32 * 1024,
    )
    expected_descriptor = {
        "schemaVersion": "nodedc.engine.deploy-transition/v1",
        "id": "engine-mcp-gelios-items-envelope-v12",
        "component": "engine",
        "scope": "external-mcp-provider-package-catalog",
        "mcpVersion": "0.11.0",
        "predecessor": "engine-mcp-l2-execution-plan-sandbox-runtime-v4",
        "providerPackageTransition": {
            "from": "gelios.provider.v11",
            "to": "gelios.provider.v12",
            "capabilityId": "gelios.units.identity.read",
            "dataProductId": "fleet.units.identity.current.v1",
        },
        "responseEnvelope": {
            "collectionPath": "items",
            "evidence": "bounded-structural-profile",
            "observedCardinality": 107,
            "rawValuesCaptured": False,
        },
        "catalogPolicy": {
            "historicalExecutionPackagePreserved": "gelios.provider.v11",
            "activeSecurityAuthority": "gelios.provider.v12",
            "ambiguousIdentityAuthority": "forbidden",
        },
        "boundaries": {
            "compilerChanged": False,
            "n8nCoreChanged": False,
            "l1Changed": False,
            "ontologyChanged": False,
            "credentialsChanged": False,
            "rawProviderValuesIncluded": False,
        },
    }
    if descriptor != expected_descriptor:
        die("Engine MCP Gelios items envelope descriptor mismatch")

    execution_catalog = read_strict_json(
        payload_dir
        / "nodedc-source/server/assets/execution-plans/v1/catalog.json",
        "Engine MCP Gelios items envelope execution catalog",
        max_bytes=2 * 1024 * 1024,
    )
    security_catalog = read_strict_json(
        payload_dir
        / "nodedc-source/server/assets/provider-packages/v1/catalog.json",
        "Engine MCP Gelios items envelope security catalog",
        max_bytes=512 * 1024,
    )
    execution_packages = {
        item.get("id"): item
        for item in execution_catalog.get("packages", [])
        if isinstance(item, dict)
    }
    security_packages = [
        item for item in security_catalog.get("packages", [])
        if isinstance(item, dict)
    ]
    gelios_v12 = execution_packages.get("gelios.provider.v12", {})
    identity_profiles = [
        profile for profile in gelios_v12.get("profiles", [])
        if (
            profile.get("id") == "gelios.units.identity.warm.v1"
            and profile.get("dataProductId")
            == "fleet.units.identity.current.v1"
        )
    ]
    active_identity = [
        item for item in security_packages
        if item.get("id") == "gelios.provider.v12"
    ]
    if (
        "gelios.provider.v11" not in execution_packages
        or gelios_v12.get("version") != "12.0.0"
        or len(identity_profiles) != 1
        or any(item.get("id") == "gelios.provider.v11"
               for item in security_packages)
        or len(active_identity) != 1
        or [
            capability.get("id")
            for capability in active_identity[0].get("capabilities", [])
        ] != ["gelios.units.identity.read"]
    ):
        die("Engine MCP Gelios items envelope catalog authority mismatch")


def validate_engine_mcp_registered_execution_profiles_slice(
    payload_dir,
    entries,
):
    if (
        tuple(entries)
        != ENGINE_MCP_REGISTERED_EXECUTION_PROFILES_ARTIFACT_ENTRIES
    ):
        die(
            "Engine MCP registered execution profiles files.txt exact "
            "set/order mismatch"
        )
    for rel, expected_sha256 in (
        ENGINE_MCP_REGISTERED_EXECUTION_PROFILES_TARGET_SHA256.items()
    ):
        path = payload_dir / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(
                "Engine MCP registered execution profiles target is missing: "
                f"{rel}"
            )
        if (
            stat.S_ISLNK(path_stat.st_mode)
            or not stat.S_ISREG(path_stat.st_mode)
            or sha256_file(path) != expected_sha256
        ):
            die(
                "Engine MCP registered execution profiles target sha256 "
                f"mismatch: {rel}"
            )

    descriptor = read_strict_json(
        payload_dir
        / ENGINE_MCP_REGISTERED_EXECUTION_PROFILES_DESCRIPTOR_REL,
        "Engine MCP registered execution profiles descriptor",
        max_bytes=32 * 1024,
    )
    expected_descriptor = {
        "schemaVersion": "nodedc.engine.deploy-transition/v1",
        "id": "engine-mcp-registered-execution-profiles-v2",
        "component": "engine",
        "predecessor": "engine-mcp-gelios-items-envelope-v12",
        "scope":
            "external-mcp-registered-execution-profiles-with-node-intelligence-attestation",
        "mcpVersion": "0.12.0",
        "catalog": {
            "schemaVersion": "nodedc.engine.execution-plan-catalog/v1",
            "registeredProfiles": 6,
            "profileRefs": "actor-and-target-scoped-opaque-ttl",
            "executionPlanDescriptorsIncluded": False,
            "providerEndpointsIncluded": False,
            "customerScopeIncluded": False,
            "credentialIdentitiesIncluded": False,
            "credentialValuesIncluded": False,
        },
        "tools": {
            "discovery": "engine_list_l2_execution_profiles",
            "planning": "engine_plan_registered_l2_execution",
            "apply": "engine_apply_l2_execution_plan_materialization",
        },
        "planning": {
            "packageResolution": "server-owned-catalog",
            "targetScope": "server-derived",
            "digests": "server-derived",
            "providerAuth": "target-local-compatible-refs",
            "materializer": "existing-immutable-two-phase",
        },
        "nodeIntelligenceAttestation": {
            "releaseId": ENGINE_NODE_INTELLIGENCE_RELEASE_ID,
            "previousGatewaySha256":
                "4a9524fd954320277042c783b7b19cbb2172f075f27652c0eebfd743ffc47872",
            "targetGatewaySha256":
                "8f04edc11251de86b825351c92338be9537207887cf802474b6b6d8c3cce4077",
            "sidecarImageChanged": False,
            "nodeIntelligenceSourceChanged": False,
        },
        "foundationSha256": {
            "nodedc-source/server/l2ExecutionPlan/compiler.js":
                "64f5196a83018505c6dac77a0f8674c27941257a874eed9b024c1c94f169be2b",
            "nodedc-source/server/l2ExecutionPlan/materializer.js":
                "dabf0073520049d7a04d1962b29e591ae092b87b287a50534ad2d98b03ae683c",
            "nodedc-source/server/deployTransitions/geliosItemsEnvelopeV12.json":
                "16e39f54ebae776de9acfdf0078c79291310eeca5a1f720eb8b82496f4d419a3",
        },
        "boundaries": {
            "n8nCoreChanged": False,
            "l1Changed": False,
            "l2GraphChanged": False,
            "engineUiChanged": False,
            "databaseChanged": False,
            "credentialsChanged": False,
            "foundryChanged": False,
            "ontologyChanged": False,
            "mcpNginxChanged": False,
            "embeddedAiWorkspaceChanged": False,
            "nodeIntelligenceAttestationChanged": True,
            "nodeIntelligenceImageChanged": False,
            "nodeIntelligenceSourceChanged": False,
        },
    }
    if descriptor != expected_descriptor:
        die("Engine MCP registered execution profiles descriptor mismatch")

    node_intelligence_descriptor = read_engine_node_intelligence_descriptor(
        payload_dir / ENGINE_NODE_INTELLIGENCE_DESCRIPTOR_REL,
        "Engine MCP registered execution profiles node-intelligence descriptor",
    )
    if (
        node_intelligence_descriptor.get("action") != "activate"
        or node_intelligence_descriptor.get("releaseId")
        != ENGINE_NODE_INTELLIGENCE_RELEASE_ID
        or node_intelligence_descriptor.get("source", {}).get("gatewaySha256")
        != ENGINE_MCP_REGISTERED_EXECUTION_PROFILES_TARGET_SHA256[
            ENGINE_NODE_INTELLIGENCE_GATEWAY_REL
        ]
    ):
        die(
            "Engine MCP registered execution profiles node-intelligence "
            "attestation mismatch"
        )

    catalog = read_strict_json(
        payload_dir
        / "nodedc-source/server/assets/execution-plans/v1/catalog.json",
        "Engine MCP registered execution profiles catalog",
        max_bytes=4 * 1024 * 1024,
    )
    registered = [
        (provider_package, profile)
        for provider_package in catalog.get("packages", [])
        if isinstance(provider_package, dict)
        for profile in provider_package.get("profiles", [])
        if (
            isinstance(profile, dict)
            and isinstance(profile.get("executionPlanTemplate"), dict)
        )
    ]
    if len(registered) != 6:
        die("Engine MCP registered execution profiles count mismatch")
    for provider_package, profile in registered:
        template = profile["executionPlanTemplate"]
        if (
            profile.get("cadence")
            not in {"hot", "warm", "cold", "on_demand"}
            or profile.get("dataClass")
            not in {"operational", "restricted", "internal", "unclassified"}
            or template.get("compilerVersion") != "1.4.0"
            or template.get("package", {}).get("id")
            != provider_package.get("id")
            or template.get("connection", {}).get("collectionProfileId")
            != profile.get("id")
            or template.get("collectionProfile", {}).get("dataProductId")
            != profile.get("dataProductId")
            or not str(
                template.get("bindings", {})
                .get("provider", {})
                .get("reference", "")
            ).startswith("ndc-credref:catalog-build-")
        ):
            die("Engine MCP registered execution profile template mismatch")

    gateway = (
        payload_dir
        / "nodedc-source/server/routes/engineAgentGateway.js"
    ).read_text(encoding="utf-8")
    resolver = (
        payload_dir
        / "nodedc-source/server/l2ExecutionPlan/registeredProfiles.js"
    ).read_text(encoding="utf-8")
    for marker in (
        "const ENGINE_AGENT_MCP_VERSION = '0.12.0'",
        "engine_list_l2_execution_profiles",
        "engine_plan_registered_l2_execution",
    ):
        if marker not in gateway:
            die(
                "Engine MCP registered execution profiles gateway marker "
                f"missing: {marker}"
            )
    if (
        "registered_execution_profile_ref_scope_denied" not in resolver
        or "targetBoundPlan" not in resolver
        or re.search(r"gelios|robot2b", resolver, re.IGNORECASE)
    ):
        die("Engine MCP registered execution profiles resolver boundary mismatch")


def validate_engine_mcp_gelios_units_items_slice(payload_dir, entries):
    if tuple(entries) != ENGINE_MCP_GELIOS_UNITS_ITEMS_ARTIFACT_ENTRIES:
        die(
            "Engine MCP Gelios units items envelope files.txt exact "
            "set/order mismatch"
        )
    for rel, expected_sha256 in (
        ENGINE_MCP_GELIOS_UNITS_ITEMS_TARGET_SHA256.items()
    ):
        path = payload_dir / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(f"Engine MCP Gelios units items envelope target missing: {rel}")
        if (
            stat.S_ISLNK(path_stat.st_mode)
            or not stat.S_ISREG(path_stat.st_mode)
            or sha256_file(path) != expected_sha256
        ):
            die(
                "Engine MCP Gelios units items envelope target sha256 "
                f"mismatch: {rel}"
            )

    descriptor = read_strict_json(
        payload_dir / ENGINE_MCP_GELIOS_UNITS_ITEMS_DESCRIPTOR_REL,
        "Engine MCP Gelios units items envelope descriptor",
        max_bytes=32 * 1024,
    )
    if descriptor != {
        "schemaVersion": "nodedc.engine.deploy-transition/v1",
        "id": "engine-mcp-gelios-units-items-envelope-v12-patch1",
        "component": "engine",
        "predecessor": "engine-mcp-registered-execution-profiles-v2",
        "scope": "server-owned-registered-profile-envelope-correction",
        "mcpVersion": "0.12.0",
        "providerPackage": {
            "id": "gelios.provider.v12",
            "predecessorVersion": "12.0.0",
            "targetVersion": "12.0.1",
            "capabilityId": "gelios.units.current.read",
            "responseCollectionPath": "items",
        },
        "registeredProfile": {
            "id": "gelios.units.profile.cold.v1",
            "dataProductId": "fleet.units.profile.current.v1",
            "compilerVersion": "1.4.0",
            "materializer": "existing-immutable-two-phase",
        },
        "foundationSha256": dict(
            ENGINE_MCP_GELIOS_UNITS_ITEMS_FOUNDATION_SHA256
        ),
        "boundaries": {
            "n8nCoreChanged": False,
            "l1Changed": False,
            "l2GraphChanged": False,
            "engineRuntimeCodeChanged": False,
            "engineUiChanged": False,
            "databaseChanged": False,
            "credentialsChanged": False,
            "foundryChanged": False,
            "ontologyChanged": False,
            "mcpNginxChanged": False,
            "embeddedAiWorkspaceChanged": False,
            "providerEndpointsChanged": False,
        },
    }:
        die("Engine MCP Gelios units items envelope descriptor mismatch")

    execution_catalog = read_strict_json(
        payload_dir
        / "nodedc-source/server/assets/execution-plans/v1/catalog.json",
        "Engine MCP Gelios units items envelope execution catalog",
        max_bytes=4 * 1024 * 1024,
    )
    execution_packages = [
        item for item in execution_catalog.get("packages", [])
        if item.get("id") == "gelios.provider.v12"
    ]
    if len(execution_packages) != 1:
        die("Engine MCP Gelios units items execution package cardinality mismatch")
    provider_package = execution_packages[0]
    profiles = provider_package.get("profiles", [])
    technical_profiles = [
        item for item in profiles
        if item.get("id") == "gelios.units.profile.cold.v1"
    ]
    units_profiles = [
        item for item in profiles
        if "gelios.units.current.read" in item.get("capabilityIds", [])
    ]
    if (
        provider_package.get("version") != "12.0.1"
        or len(profiles) != 6
        or len(technical_profiles) != 1
        or len(units_profiles) != 4
    ):
        die("Engine MCP Gelios units items registered profile mismatch")
    for profile in profiles:
        template = profile.get("executionPlanTemplate", {})
        if template.get("compilerVersion") != "1.4.0":
            die("Engine MCP Gelios units items compiler version drift")
    for profile in units_profiles:
        extract_steps = [
            step for step in (
                profile.get("executionPlanTemplate", {}).get("steps", [])
            )
            if (
                step.get("kind") == "extract_items"
                and step.get("config", {}).get("capabilityId")
                == "gelios.units.current.read"
            )
        ]
        if (
            len(extract_steps) != 1
            or extract_steps[0].get("config", {})
            .get("response", {}).get("collectionPaths", [None])[:1]
            != ["items"]
        ):
            die(
                "Engine MCP Gelios units items response envelope mismatch: "
                f"{profile.get('id')}"
            )

    security_catalog = read_strict_json(
        payload_dir
        / "nodedc-source/server/assets/provider-packages/v1/catalog.json",
        "Engine MCP Gelios units items security catalog",
        max_bytes=2 * 1024 * 1024,
    )
    security_packages = [
        item for item in security_catalog.get("packages", [])
        if item.get("id") == "gelios.provider.v12"
    ]
    if (
        len(security_packages) != 1
        or security_packages[0].get("version") != "12.0.1"
        or [
            capability.get("id")
            for capability in security_packages[0].get("capabilities", [])
        ] != ["gelios.units.identity.read"]
    ):
        die("Engine MCP Gelios units items security authority mismatch")


def validate_engine_agent_full_grant_migration_slice(payload_dir, entries):
    if tuple(entries) != ENGINE_AGENT_FULL_GRANT_MIGRATION_ARTIFACT_ENTRIES:
        die("Engine agent full grant migration files.txt exact set/order mismatch")
    store_path = payload_dir / ENGINE_AGENT_FULL_GRANT_MIGRATION_STORE_REL
    try:
        store_source = store_path.read_text(encoding="utf-8")
    except (OSError, UnicodeDecodeError):
        die("Engine agent full grant migration store is unreadable")
    if sha256_file(store_path) != ENGINE_AGENT_FULL_GRANT_MIGRATION_TARGET_SHA256:
        die("Engine agent full grant migration target sha256 mismatch")
    required = (
        "const STORE_VERSION = 2",
        "export const ENGINE_AGENT_FULL_DEVELOPER_PROFILE = 'full-developer'",
        "export const ENGINE_AGENT_CUSTOM_PROFILE = 'custom'",
        "const LEGACY_FULL_DEVELOPER_SCOPES = Object.freeze([",
        "'engine:l2:data-product-publish-grant:plan'",
        "'engine:l2:data-product-publish-grant:write'",
        "const migrateLegacyFullDeveloper = sourceVersion === 1",
        "LEGACY_FULL_DEVELOPER_SCOPES.every((scope) => scopes.includes(scope))",
        "profile === ENGINE_AGENT_FULL_DEVELOPER_PROFILE ? [...ENGINE_AGENT_SCOPES] : scopes",
        "throw new Error('engine_agent_store_version_unsupported')",
    )
    if any(value not in store_source for value in required):
        die("Engine agent full grant migration contract mismatch")
    if re.search(r"gelios|robot2b", store_source, re.IGNORECASE):
        die("Engine agent full grant migration provider logic is forbidden")


def current_engine_n8n_transition_descriptor():
    path = component_root("engine") / ENGINE_N8N_TRANSITION_DESCRIPTOR_REL
    if not path.exists():
        return None
    if path.is_symlink() or not path.is_file():
        die("installed Engine n8n transition descriptor is unsafe")
    return read_engine_n8n_transition_descriptor(path, "installed Engine n8n transition descriptor")


def current_engine_node_intelligence_descriptor():
    path = component_root("engine") / ENGINE_NODE_INTELLIGENCE_DESCRIPTOR_REL
    if not path.exists():
        return None
    if path.is_symlink() or not path.is_file():
        die("installed Engine node-intelligence descriptor is unsafe")
    return read_engine_node_intelligence_descriptor(
        path,
        "installed Engine node-intelligence descriptor",
    )


def validate_installed_engine_node_intelligence_source(
    descriptor,
    expected_gateway_sha256=None,
):
    if descriptor is None or descriptor.get("action") != "activate":
        die("active Engine node-intelligence descriptor is required")
    root = component_root("engine")
    source_root = root / ENGINE_NODE_INTELLIGENCE_SOURCE_REL
    expected_source_files = {
        "catalog.js": descriptor["source"]["catalogSha256"],
        "upstreamMcpClient.js": descriptor["source"]["upstreamClientSha256"],
        "upstreamProjection.js": descriptor["source"]["upstreamProjectionSha256"],
    }
    try:
        source_stat = source_root.lstat()
    except FileNotFoundError:
        die("installed Engine node-intelligence source is missing")
    if stat.S_ISLNK(source_stat.st_mode) or not stat.S_ISDIR(source_stat.st_mode):
        die("installed Engine node-intelligence source is unsafe")
    actual_files = {
        child.relative_to(source_root).as_posix()
        for child in source_root.rglob("*")
        if child.is_file()
    }
    if actual_files != set(expected_source_files):
        die("installed Engine node-intelligence source file set mismatch")
    for rel, expected_sha256 in expected_source_files.items():
        path = source_root / rel
        if path.is_symlink() or sha256_file(path) != expected_sha256:
            die(f"installed Engine node-intelligence source drift detected: {rel}")
    gateway_sha256 = (
        expected_gateway_sha256
        if expected_gateway_sha256 is not None
        else descriptor["source"]["gatewaySha256"]
    )
    if not re.fullmatch(r"[a-f0-9]{64}", str(gateway_sha256)):
        die("installed Engine node-intelligence gateway expectation is invalid")
    gateway = root / ENGINE_NODE_INTELLIGENCE_GATEWAY_REL
    if gateway.is_symlink() or sha256_file(gateway) != gateway_sha256:
        die("installed Engine node-intelligence gateway drift detected")
    override = root / ENGINE_NODE_INTELLIGENCE_OVERRIDE_REL
    try:
        override_stat = override.lstat()
        override_text = override.read_text(encoding="utf-8")
    except (FileNotFoundError, OSError, UnicodeDecodeError):
        die("installed Engine node-intelligence Compose override is missing")
    if stat.S_ISLNK(override_stat.st_mode) or not stat.S_ISREG(override_stat.st_mode):
        die("installed Engine node-intelligence Compose override is unsafe")
    if (
        override_text != expected_engine_node_intelligence_compose_override()
        or sha256_file(override) != descriptor["source"]["composeOverrideSha256"]
    ):
        die("installed Engine node-intelligence Compose override drift detected")
    readme = root / ENGINE_NODE_INTELLIGENCE_SERVICE_ROOT_REL / "README.md"
    if readme.is_symlink() or sha256_file(readme) != descriptor["source"]["readmeSha256"]:
        die("installed Engine node-intelligence README drift detected")
    return gateway_sha256


def preflight_engine_node_intelligence_predecessor(payload_dir):
    candidate = read_engine_node_intelligence_descriptor(
        payload_dir / ENGINE_NODE_INTELLIGENCE_DESCRIPTOR_REL,
        "candidate Engine node-intelligence descriptor",
    )
    root = component_root("engine")
    compose_path = root / "docker-compose.yml"
    gateway_path = root / ENGINE_NODE_INTELLIGENCE_GATEWAY_REL
    for path, label in (
        (compose_path, "Compose"),
        (gateway_path, "gateway"),
    ):
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(f"Engine node-intelligence predecessor {label} is missing")
        if stat.S_ISLNK(path_stat.st_mode) or not stat.S_ISREG(path_stat.st_mode):
            die(f"Engine node-intelligence predecessor {label} is unsafe")
    if sha256_file(compose_path) != candidate["predecessor"]["composeSha256"]:
        die("Engine node-intelligence predecessor Compose drift detected")

    current = current_engine_node_intelligence_descriptor()
    current_state = (
        current["releaseId"]
        if current is not None and current["action"] == "activate"
        else "inactive"
    )
    if current_state != candidate["expectedCurrent"]:
        die(
            "Engine node-intelligence predecessor state mismatch: "
            f"expected={candidate['expectedCurrent']} actual={current_state}"
        )
    actual_gateway_sha256 = sha256_file(gateway_path)
    if actual_gateway_sha256 != candidate["predecessor"]["gatewaySha256"]:
        die(
            "Engine node-intelligence predecessor gateway drift detected: "
            f"expected={candidate['predecessor']['gatewaySha256']} "
            f"actual={actual_gateway_sha256}"
        )
    if candidate["action"] == "activate":
        if current is not None and current["action"] == "activate":
            die("Engine node-intelligence activation requires an inactive predecessor")
        override = root / ENGINE_NODE_INTELLIGENCE_OVERRIDE_REL
        if override.exists() or override.is_symlink():
            die("inactive Engine node-intelligence predecessor still has a Compose override")
    else:
        validate_installed_engine_node_intelligence_source(current)

    backend = preflight_engine_credential_backend_runtime()
    if backend["mode"] != "verified-derived-retry":
        die("Engine node-intelligence requires the active immutable backend")
    return {
        "action": candidate["action"],
        "current_state": current_state,
        "gateway_sha256": actual_gateway_sha256,
        "backend_mode": backend["mode"],
        "descriptor": candidate,
    }


def validate_engine_l2_closed_loop_recovery_evidence():
    backup_dir = BACKUPS_DIR / ENGINE_L2_CLOSED_LOOP_RECOVERY_BACKUP_ID
    try:
        backup_stat = backup_dir.lstat()
    except FileNotFoundError:
        die("Engine L2 closed-loop recovery backup is missing")
    if stat.S_ISLNK(backup_stat.st_mode) or not stat.S_ISDIR(backup_stat.st_mode):
        die("Engine L2 closed-loop recovery backup is unsafe")
    backup_names = {
        child.name
        for child in backup_dir.iterdir()
    }
    if backup_names != set(ENGINE_L2_CLOSED_LOOP_RECOVERY_BACKUP_SHA256):
        die("Engine L2 closed-loop recovery backup file set mismatch")
    for name, expected in ENGINE_L2_CLOSED_LOOP_RECOVERY_BACKUP_SHA256.items():
        path = backup_dir / name
        path_stat = path.lstat()
        if (
            stat.S_ISLNK(path_stat.st_mode)
            or not stat.S_ISREG(path_stat.st_mode)
            or sha256_file(path) != expected
        ):
            die(f"Engine L2 closed-loop recovery backup drift detected: {name}")

    failed_artifact = FAILED_DIR / ENGINE_L2_CLOSED_LOOP_FAILED_ARTIFACT
    try:
        failed_stat = failed_artifact.lstat()
    except FileNotFoundError:
        die("Engine L2 closed-loop failed artifact is missing")
    if (
        stat.S_ISLNK(failed_stat.st_mode)
        or not stat.S_ISREG(failed_stat.st_mode)
        or sha256_file(failed_artifact)
        != ENGINE_L2_CLOSED_LOOP_FAILED_ARTIFACT_SHA256
    ):
        die("Engine L2 closed-loop failed artifact evidence mismatch")

    try:
        state_stat = FAILED_STATE_FILE.lstat()
        state_lines = FAILED_STATE_FILE.read_text(encoding="utf-8").splitlines()
    except (FileNotFoundError, OSError, UnicodeDecodeError):
        die("Engine L2 closed-loop failed journal is unreadable")
    if stat.S_ISLNK(state_stat.st_mode) or not stat.S_ISREG(state_stat.st_mode):
        die("Engine L2 closed-loop failed journal is unsafe")
    records = []
    for line in state_lines:
        try:
            value = json.loads(line)
        except json.JSONDecodeError:
            die("Engine L2 closed-loop failed journal contains invalid JSON")
        if (
            isinstance(value, dict)
            and value.get("id") == ENGINE_L2_CLOSED_LOOP_FAILED_PATCH_ID
        ):
            records.append(value)
    if len(records) != 1:
        die("Engine L2 closed-loop failed journal evidence count mismatch")
    record = records[0]
    if (
        record.get("artifact") != ENGINE_L2_CLOSED_LOOP_FAILED_ARTIFACT
        or record.get("backup_id") != ENGINE_L2_CLOSED_LOOP_RECOVERY_BACKUP_ID
        or record.get("component") != "engine"
        or record.get("sha256") != ENGINE_L2_CLOSED_LOOP_FAILED_ARTIFACT_SHA256
        or record.get("started_apply") is not True
        or record.get("rollback_status") != "not-required"
        or record.get("status") != "failed"
        or record.get("message")
        != "installed Engine node-intelligence gateway drift detected"
    ):
        die("Engine L2 closed-loop failed journal evidence mismatch")
    return backup_dir


def preflight_engine_l2_closed_loop_predecessor(payload_dir):
    candidate = validate_engine_l2_closed_loop_payload(
        payload_dir,
        ENGINE_L2_CLOSED_LOOP_ARTIFACT_ENTRIES,
    )
    recovery_backup = validate_engine_l2_closed_loop_recovery_evidence()
    root = component_root("engine")
    actual = collect_exact_files(
        root,
        ENGINE_L2_CLOSED_LOOP_ARTIFACT_ENTRIES,
        "installed Engine L2 closed-loop partial state",
    )
    if actual != ENGINE_L2_CLOSED_LOOP_PARTIAL_SHA256:
        changed = sorted(
            set(actual) ^ set(ENGINE_L2_CLOSED_LOOP_PARTIAL_SHA256)
            | {
                rel
                for rel in set(actual) & set(ENGINE_L2_CLOSED_LOOP_PARTIAL_SHA256)
                if actual[rel] != ENGINE_L2_CLOSED_LOOP_PARTIAL_SHA256[rel]
            }
        )
        detail = changed[0] if changed else "unknown"
        die(f"Engine L2 closed-loop partial predecessor drift detected: {detail}")

    nginx_entries = ("nginx-html/index.html", "nginx-html/assets")
    nginx_actual = collect_exact_files(
        root,
        nginx_entries,
        "installed Engine L2 closed-loop nginx publication",
    )
    nginx_expected = {
        "nginx-html/index.html": ENGINE_L2_CLOSED_LOOP_PARTIAL_SHA256[
            "nodedc-source/dist/index.html"
        ],
        "nginx-html/assets/index-Bim2pv1P.css":
            ENGINE_L2_CLOSED_LOOP_PARTIAL_SHA256[
                "nodedc-source/dist/assets/index-Bim2pv1P.css"
            ],
        "nginx-html/assets/index-CqvJfRRS.js":
            ENGINE_L2_CLOSED_LOOP_PARTIAL_SHA256[
                "nodedc-source/dist/assets/index-CqvJfRRS.js"
            ],
    }
    if nginx_actual != nginx_expected:
        die("Engine L2 closed-loop nginx partial predecessor drift detected")

    installed = current_engine_node_intelligence_descriptor()
    if (
        installed is None
        or installed.get("action") != "activate"
        or sha256_file(root / ENGINE_L2_CLOSED_LOOP_DESCRIPTOR_REL)
        != ENGINE_L2_CLOSED_LOOP_PARTIAL_SHA256[
            ENGINE_L2_CLOSED_LOOP_DESCRIPTOR_REL
        ]
    ):
        die("Engine L2 closed-loop partial descriptor mismatch")
    expected_candidate = json.loads(json.dumps(installed))
    expected_candidate["source"]["gatewaySha256"] = (
        ENGINE_L2_CLOSED_LOOP_TARGET_SHA256[
            ENGINE_NODE_INTELLIGENCE_GATEWAY_REL
        ]
    )
    if candidate != expected_candidate:
        die("Engine L2 closed-loop descriptor crosses node-intelligence boundary")
    validate_installed_engine_node_intelligence_source(
        installed,
        expected_gateway_sha256=ENGINE_L2_CLOSED_LOOP_PARTIAL_SHA256[
            ENGINE_NODE_INTELLIGENCE_GATEWAY_REL
        ],
    )
    backend = preflight_engine_credential_backend_runtime(
        expected_node_intelligence_gateway_sha256=
            ENGINE_L2_CLOSED_LOOP_PARTIAL_SHA256[
                ENGINE_NODE_INTELLIGENCE_GATEWAY_REL
            ],
    )
    if backend["mode"] != "verified-derived-retry":
        die("Engine L2 closed-loop requires the active immutable backend")
    app_container_id = engine_compose_service_container_id_for_gateway(
        "app",
        ENGINE_L2_CLOSED_LOOP_PARTIAL_SHA256[
            ENGINE_NODE_INTELLIGENCE_GATEWAY_REL
        ],
    )
    return {
        "mode": "failed-030-partial-source-reconciliation",
        "descriptor": candidate,
        "recovery_backup": recovery_backup,
        "predecessor_gateway_sha256": installed["source"]["gatewaySha256"],
        "partial_gateway_sha256": ENGINE_L2_CLOSED_LOOP_PARTIAL_SHA256[
            ENGINE_NODE_INTELLIGENCE_GATEWAY_REL
        ],
        "target_gateway_sha256": candidate["source"]["gatewaySha256"],
        "backend_mode": backend["mode"],
        "backend_container_id": backend["container_id"],
        "app_container_id": app_container_id,
    }


def validate_engine_n8n_staged_release(descriptor):
    release_rel = f"releases/n8n-nodes-ndc/{descriptor['releaseId']}"
    release_dir = N8N_PRIVATE_EXTENSION_RELEASES_ROOT / release_rel
    current = N8N_PRIVATE_EXTENSION_RELEASES_ROOT
    for part in PurePosixPath(release_rel).parts:
        current = current / part
        try:
            current_stat = current.lstat()
        except FileNotFoundError:
            die(f"staged private extension release is missing: {release_rel}")
        if stat.S_ISLNK(current_stat.st_mode):
            die(f"staged private extension release symlink rejected: {current}")
    validate_n8n_private_extension_release(N8N_PRIVATE_EXTENSION_RELEASES_ROOT, [release_rel])
    release = read_strict_json(release_dir / "release.json", "staged private extension release manifest")
    if release.get("releaseId") != descriptor["releaseId"]:
        die("staged private extension release id mismatch")
    if release.get("package", {}).get("version") != descriptor["packageVersion"]:
        die("staged private extension package version mismatch")
    if release.get("package", {}).get("sha256") != descriptor["packageSha256"]:
        die("staged private extension package sha256 mismatch")
    for path in [release_dir, *release_dir.rglob("*")]:
        path_stat = path.lstat()
        if path_stat.st_uid != 0 or path_stat.st_gid != 0:
            die(f"staged private extension release ownership mismatch: {path}")
        expected_mode = 0o555 if stat.S_ISDIR(path_stat.st_mode) else 0o444
        if stat.S_IMODE(path_stat.st_mode) != expected_mode:
            die(f"staged private extension release mode mismatch: {path}")
    return release_dir


def load_artifact(artifact, work_dir):
    safe_extract(artifact, work_dir)

    manifest_path = work_dir / "manifest.env"
    files_path = work_dir / "files.txt"
    payload_dir = work_dir / "payload"

    if not manifest_path.is_file():
        die("manifest.env missing after extract")
    if not files_path.is_file():
        die("files.txt missing after extract")
    if not payload_dir.is_dir():
        die("payload directory missing after extract")

    manifest = parse_manifest(manifest_path)
    entries = parse_files_list(files_path)

    for rel in entries:
        allowed_payload_path(manifest["component"], rel)
        if not (payload_dir / rel).exists():
            die(f"files.txt entry missing in payload: {rel}")

    validate_payload_tree(manifest["component"], payload_dir, entries)
    if is_device_plane_postgres_bootstrap_slice(
        manifest["component"],
        entries,
    ):
        validate_device_plane_postgres_bootstrap_payload(payload_dir)
    if manifest["component"] == "n8n-private-extension":
        validate_n8n_private_extension_release(payload_dir, entries)
    if manifest["component"] == "engine":
        touches_private_extension = any(
            rel == "nodedc-source/services/n8n/private-extensions"
            or rel.startswith("nodedc-source/services/n8n/private-extensions/")
            for rel in entries
        )
        if touches_private_extension and not is_engine_n8n_transition(manifest["component"], entries):
            die("Engine private-extension payload requires the canonical transition descriptor")
        if is_engine_n8n_transition(manifest["component"], entries):
            validate_engine_n8n_transition(payload_dir, entries)
        touches_node_intelligence = any(
            rel == ENGINE_NODE_INTELLIGENCE_SOURCE_REL
            or rel.startswith(ENGINE_NODE_INTELLIGENCE_SOURCE_REL + "/")
            or rel == ENGINE_NODE_INTELLIGENCE_SERVICE_ROOT_REL
            or rel.startswith(ENGINE_NODE_INTELLIGENCE_SERVICE_ROOT_REL + "/")
            for rel in entries
        )
        if (
            touches_node_intelligence
            and not is_engine_node_intelligence_transition(manifest["component"], entries)
            and not is_engine_mcp_control_plane_slice(manifest["component"], entries)
            and not is_engine_mcp_ontology_sdk_slice(manifest["component"], entries)
            and not is_engine_mcp_autonomy_provider_v5_slice(manifest["component"], entries)
            and not is_engine_l2_closed_loop_slice(manifest["component"], entries)
            and not is_engine_mcp_telemetry_catalog_slice(
                manifest["component"],
                entries,
            )
            and not is_engine_mcp_execution_plan_materialization_slice(
                manifest["component"],
                entries,
            )
            and not is_engine_mcp_execution_plan_module_ownership_slice(
                manifest["component"],
                entries,
            )
            and not is_engine_mcp_normalized_identity_search_slice(
                manifest["component"],
                entries,
            )
            and not is_engine_mcp_registered_execution_profiles_slice(
                manifest["component"],
                entries,
            )
            and not is_engine_provider_authority_diagnostics_slice(
                manifest["component"],
                entries,
            )
        ):
            die("Engine node-intelligence payload requires the canonical transition")
        if is_engine_node_intelligence_transition(manifest["component"], entries):
            validate_engine_node_intelligence_transition(payload_dir, entries)
        if is_engine_mcp_control_plane_slice(manifest["component"], entries):
            validate_engine_mcp_control_plane_payload(payload_dir, entries)
        if is_engine_mcp_ontology_sdk_slice(manifest["component"], entries):
            validate_engine_mcp_ontology_sdk_payload(payload_dir, entries)
        if is_engine_mcp_autonomy_provider_v5_slice(manifest["component"], entries):
            validate_engine_mcp_autonomy_provider_v5_payload(payload_dir, entries)
        if is_engine_l2_closed_loop_slice(manifest["component"], entries):
            validate_engine_l2_closed_loop_payload(payload_dir, entries)
        if is_engine_composite_provider_v4_slice(manifest["component"], entries):
            validate_engine_composite_provider_v4_slice(payload_dir, entries)
        if is_engine_provider_rotating_slot_slice(manifest["component"], entries):
            validate_engine_provider_rotating_slot_slice(payload_dir, entries)
        if is_engine_provider_authority_diagnostics_slice(manifest["component"], entries):
            validate_engine_provider_authority_diagnostics_slice(payload_dir, entries)
        if is_engine_depttrans_zone_authority_v1_slice(manifest["component"], entries):
            validate_engine_depttrans_zone_authority_v1_slice(payload_dir, entries)
        if is_engine_provider_target_host_policy_slice(manifest["component"], entries):
            validate_engine_provider_target_host_policy_slice(payload_dir, entries)
        if is_engine_mcp_execution_profile_decoder_slice(
            manifest["component"],
            entries,
        ):
            validate_engine_mcp_execution_profile_decoder_slice(payload_dir, entries)
        if is_engine_mcp_telemetry_catalog_slice(manifest["component"], entries):
            validate_engine_mcp_telemetry_catalog_slice(payload_dir, entries)
        if is_engine_mcp_execution_plan_materialization_slice(
            manifest["component"],
            entries,
        ):
            validate_engine_mcp_execution_plan_materialization_slice(
                payload_dir,
                entries,
            )
        if is_engine_mcp_execution_plan_telemetry_runtime_slice(
            manifest["component"],
            entries,
        ):
            validate_engine_mcp_execution_plan_telemetry_runtime_slice(
                payload_dir,
                entries,
            )
        if is_engine_mcp_execution_plan_module_ownership_slice(
            manifest["component"],
            entries,
        ):
            validate_engine_mcp_execution_plan_module_ownership_slice(
                payload_dir,
                entries,
            )
        if is_engine_mcp_normalized_identity_search_slice(
            manifest["component"],
            entries,
        ):
            validate_engine_mcp_normalized_identity_search_slice(
                payload_dir,
                entries,
            )
        if is_engine_mcp_l1_credential_reuse_slice(
            manifest["component"],
            entries,
        ):
            validate_engine_mcp_l1_credential_reuse_slice(
                payload_dir,
                entries,
            )
        if is_engine_mcp_l1_credential_provenance_slice(
            manifest["component"],
            entries,
        ):
            validate_engine_mcp_l1_credential_provenance_slice(
                payload_dir,
                entries,
            )
        if is_engine_mcp_execution_plan_sandbox_runtime_slice(
            manifest["component"],
            entries,
        ):
            validate_engine_mcp_execution_plan_sandbox_runtime_slice(
                payload_dir,
                entries,
            )
        if is_engine_mcp_gelios_items_envelope_slice(
            manifest["component"],
            entries,
        ):
            validate_engine_mcp_gelios_items_envelope_slice(
                payload_dir,
                entries,
            )
        if is_engine_mcp_registered_execution_profiles_slice(
            manifest["component"],
            entries,
        ):
            validate_engine_mcp_registered_execution_profiles_slice(
                payload_dir,
                entries,
            )
        if is_engine_mcp_gelios_units_items_slice(
            manifest["component"],
            entries,
        ):
            validate_engine_mcp_gelios_units_items_slice(
                payload_dir,
                entries,
            )
        if is_engine_provider_security_catalog_slice(manifest["component"], entries):
            validate_engine_provider_security_catalog_payload(payload_dir, entries)
        if touches_engine_credential_sink(manifest["component"], entries):
            validate_engine_credential_sink_slice(payload_dir, entries)
        if (
            not is_engine_mcp_control_plane_slice(manifest["component"], entries)
            and not is_engine_mcp_ontology_sdk_slice(manifest["component"], entries)
            and not is_engine_mcp_autonomy_provider_v5_slice(manifest["component"], entries)
            and not is_engine_composite_provider_v4_slice(manifest["component"], entries)
            and not is_engine_provider_rotating_slot_slice(manifest["component"], entries)
            and not is_engine_provider_authority_diagnostics_slice(manifest["component"], entries)
            and not is_engine_depttrans_zone_authority_v1_slice(manifest["component"], entries)
            and not is_engine_provider_target_host_policy_slice(manifest["component"], entries)
            and not is_engine_mcp_execution_profile_decoder_slice(
                manifest["component"],
                entries,
            )
            and not is_engine_mcp_telemetry_catalog_slice(
                manifest["component"],
                entries,
            )
            and not is_engine_mcp_execution_plan_materialization_slice(
                manifest["component"],
                entries,
            )
            and not is_engine_mcp_execution_plan_telemetry_runtime_slice(
                manifest["component"],
                entries,
            )
            and not is_engine_mcp_execution_plan_module_ownership_slice(
                manifest["component"],
                entries,
            )
            and not is_engine_mcp_normalized_identity_search_slice(
                manifest["component"],
                entries,
            )
            and not is_engine_mcp_l1_credential_reuse_slice(
                manifest["component"],
                entries,
            )
            and not is_engine_mcp_l1_credential_provenance_slice(
                manifest["component"],
                entries,
            )
            and not is_engine_mcp_execution_plan_sandbox_runtime_slice(
                manifest["component"],
                entries,
            )
            and not is_engine_mcp_gelios_items_envelope_slice(
                manifest["component"],
                entries,
            )
            and not is_engine_mcp_registered_execution_profiles_slice(
                manifest["component"],
                entries,
            )
            and not is_engine_mcp_gelios_units_items_slice(
                manifest["component"],
                entries,
            )
            and (
                touches_engine_data_product_publish_grant(entries)
                or ENGINE_DATA_PRODUCT_PUBLISH_GRANT_OVERRIDE_REL in entries
            )
        ):
            validate_engine_data_product_publish_grant_slice(payload_dir, entries)
        elif (
            not is_engine_mcp_control_plane_slice(manifest["component"], entries)
            and not is_engine_mcp_ontology_sdk_slice(manifest["component"], entries)
            and not is_engine_mcp_autonomy_provider_v5_slice(manifest["component"], entries)
            and ENGINE_AGENT_FULL_GRANT_MIGRATION_STORE_REL in entries
        ):
            validate_engine_agent_full_grant_migration_slice(payload_dir, entries)
    return manifest, entries, payload_dir


def load_state(path):
    if not path.exists():
        return []
    rows = []
    with path.open("r", encoding="utf-8") as f:
        for line in f:
            line = line.strip()
            if not line:
                continue
            rows.append(json.loads(line))
    return rows


def append_jsonl(path, row):
    path.parent.mkdir(parents=True, exist_ok=True)
    with path.open("a", encoding="utf-8") as f:
        f.write(json.dumps(row, ensure_ascii=False, sort_keys=True) + "\n")


def state_has_sha(sha):
    return any(row.get("sha256") == sha for row in load_state(STATE_FILE))


def state_has_patch_id(patch_id):
    return any(row.get("id") == patch_id for row in load_state(STATE_FILE))


def reject_terminal_engine_l2_failed_artifact(manifest, sha256):
    if (
        manifest.get("id") == ENGINE_L2_CLOSED_LOOP_FAILED_PATCH_ID
        or sha256 == ENGINE_L2_CLOSED_LOOP_FAILED_ARTIFACT_SHA256
    ):
        die(
            "Engine L2 closed-loop 030 is terminal failed; "
            "use the exact registered reconciliation successor"
        )


class DeployLock:
    def __enter__(self):
        try:
            LOCK_DIR.mkdir()
        except FileExistsError:
            die(f"deploy lock is busy: {LOCK_DIR}")
        (LOCK_DIR / "pid").write_text(str(os.getpid()), encoding="utf-8")
        return self

    def __exit__(self, exc_type, exc, tb):
        shutil.rmtree(LOCK_DIR, ignore_errors=True)


def component_root(component):
    return COMPONENTS[component]["payload_root"]


def is_device_plane_postgres_bootstrap_slice(component, entries):
    return (
        component == "device-plane"
        and entries is not None
        and tuple(entries) == DEVICE_PLANE_POSTGRES_BOOTSTRAP_ENTRIES
    )


def validate_device_plane_postgres_bootstrap_payload(payload_dir):
    descriptor = read_strict_json(
        payload_dir / DEVICE_PLANE_POSTGRES_BOOTSTRAP_REL,
        "Device Plane PostgreSQL bootstrap descriptor",
        max_bytes=8 * 1024,
    )
    expected = {
        "schemaVersion": "nodedc.device-plane.postgres-bootstrap.v1",
        "service": "device-postgres",
        "volume": DEVICE_PLANE_POSTGRES_VOLUME,
        "mode": "create-if-absent",
        "ordinaryApplicationSelection": "forbidden",
        "rollbackVolumePolicy": "preserve",
    }
    if descriptor != expected:
        die("Device Plane PostgreSQL bootstrap descriptor mismatch")
    return descriptor


def preflight_device_plane_postgres_bootstrap():
    container_result = subprocess.run(
        [
            str(DOCKER),
            "container",
            "ls",
            "-a",
            "--filter",
            "label=com.docker.compose.project=nodedc-device-plane",
            "--filter",
            "label=com.docker.compose.service=device-postgres",
            "--format",
            "{{.ID}}",
        ],
        check=False,
        capture_output=True,
        text=True,
    )
    if container_result.returncode != 0:
        die("Device Plane PostgreSQL container preflight failed")
    container_ids = [
        line.strip()
        for line in container_result.stdout.splitlines()
        if line.strip()
    ]
    if container_ids:
        die("Device Plane PostgreSQL container already exists")

    volume_result = subprocess.run(
        [
            str(DOCKER),
            "volume",
            "inspect",
            DEVICE_PLANE_POSTGRES_VOLUME,
        ],
        check=False,
        stdout=subprocess.DEVNULL,
        stderr=subprocess.DEVNULL,
    )
    if volume_result.returncode == 0:
        die("Device Plane PostgreSQL volume already exists")
    if volume_result.returncode != 1:
        die("Device Plane PostgreSQL volume preflight failed")
    return "absent"


def device_plane_postgres_plan_selection(postgres_preflight):
    if postgres_preflight is None:
        return "preserved-prerequisite:not-selected"
    if postgres_preflight != "absent":
        die("Device Plane PostgreSQL plan preflight state is invalid")
    return "bootstrap-selected:create-if-absent"


def component_compose_root(component):
    return COMPONENTS[component].get("compose_root", component_root(component))


def component_compose_project(component):
    return COMPONENTS[component].get("compose_project")


def component_artifact_only(component):
    return bool(COMPONENTS[component].get("artifact_only"))


def touches_engine_credential_sink(component, entries):
    if component != "engine" or entries is None:
        return False
    return any(
        rel == "nodedc-source/server/credentialSink"
        or rel.startswith("nodedc-source/server/credentialSink/")
        or rel == "nodedc-source/server/routes/engineCredentialSink.js"
        for rel in entries
    )


# Frozen compatibility predicate retained because the last successful Engine
# credential runtime canon includes it in run_compose(). The corresponding
# Platform service is not an allowed artifact path and has no deploy branch.
def touches_engine_credential_provisioner(component, entries):
    return False


def touches_external_data_plane_files(entries):
    runtime_contract_files = {
        "platform/packages/external-provider-contract/package.json",
        "platform/packages/external-provider-contract/src/contract-version.mjs",
        "platform/packages/external-provider-contract/src/data-plane.mjs",
        "platform/packages/external-provider-contract/src/data-product.mjs",
        "platform/packages/external-provider-contract/src/intake-batch.mjs",
        "platform/packages/external-provider-contract/src/index.mjs",
        "platform/packages/external-provider-contract/src/sensitive-field-policy.mjs",
    }
    return any(
        rel == "platform/services/external-data-plane"
        or rel.startswith("platform/services/external-data-plane/")
        or rel in runtime_contract_files
        or rel == "platform/docker-compose.external-data-plane.yml"
        for rel in entries
    )


def touches_engine_data_product_publish_grant(entries):
    if entries is None:
        return False
    return any(
        rel == "nodedc-source/server/dataProductPublishGrant"
        or rel.startswith("nodedc-source/server/dataProductPublishGrant/")
        for rel in entries
    )


def is_engine_data_product_publish_grant_slice(component, entries):
    return (
        component == "engine"
        and entries is not None
        and tuple(entries) == ENGINE_DATA_PRODUCT_PUBLISH_GRANT_ARTIFACT_ENTRIES
    )


def is_engine_composite_provider_v4_slice(component, entries):
    return (
        component == "engine"
        and entries is not None
        and tuple(entries) == ENGINE_COMPOSITE_PROVIDER_V4_ARTIFACT_ENTRIES
    )


def is_engine_provider_rotating_slot_slice(component, entries):
    return (
        component == "engine"
        and entries is not None
        and tuple(entries) == ENGINE_PROVIDER_ROTATING_SLOT_ARTIFACT_ENTRIES
    )


def is_engine_provider_authority_diagnostics_slice(component, entries):
    return (
        component == "engine"
        and entries is not None
        and tuple(entries) == ENGINE_PROVIDER_AUTHORITY_DIAGNOSTICS_ARTIFACT_ENTRIES
    )


def is_engine_depttrans_zone_authority_v1_slice(component, entries):
    return (
        component == "engine"
        and entries is not None
        and tuple(entries) == ENGINE_DEPTTRANS_ZONE_AUTHORITY_V1_ARTIFACT_ENTRIES
    )


def is_engine_provider_target_host_policy_slice(component, entries):
    return (
        component == "engine"
        and entries is not None
        and tuple(entries) == ENGINE_PROVIDER_TARGET_HOST_POLICY_ARTIFACT_ENTRIES
    )


def is_engine_mcp_execution_profile_decoder_slice(component, entries):
    return (
        component == "engine"
        and entries is not None
        and tuple(entries) == ENGINE_MCP_EXECUTION_PROFILE_DECODER_ARTIFACT_ENTRIES
    )


def is_engine_mcp_telemetry_catalog_slice(component, entries):
    return (
        component == "engine"
        and entries is not None
        and tuple(entries) == ENGINE_MCP_TELEMETRY_CATALOG_ARTIFACT_ENTRIES
    )


def is_engine_mcp_execution_plan_materialization_slice(component, entries):
    return (
        component == "engine"
        and entries is not None
        and tuple(entries)
        == ENGINE_MCP_EXECUTION_PLAN_MATERIALIZATION_ARTIFACT_ENTRIES
    )


def is_engine_mcp_execution_plan_telemetry_runtime_slice(component, entries):
    return (
        component == "engine"
        and entries is not None
        and tuple(entries)
        == ENGINE_MCP_EXECUTION_PLAN_TELEMETRY_RUNTIME_ARTIFACT_ENTRIES
    )


def is_engine_mcp_execution_plan_module_ownership_slice(component, entries):
    return (
        component == "engine"
        and entries is not None
        and tuple(entries)
        == ENGINE_MCP_EXECUTION_PLAN_MODULE_OWNERSHIP_ARTIFACT_ENTRIES
    )


def is_engine_mcp_normalized_identity_search_slice(component, entries):
    return (
        component == "engine"
        and entries is not None
        and tuple(entries)
        == ENGINE_MCP_NORMALIZED_IDENTITY_SEARCH_ARTIFACT_ENTRIES
    )


def is_engine_mcp_l1_credential_reuse_slice(component, entries):
    return (
        component == "engine"
        and entries is not None
        and tuple(entries) == ENGINE_MCP_L1_CREDENTIAL_REUSE_ARTIFACT_ENTRIES
    )


def is_engine_mcp_l1_credential_provenance_slice(component, entries):
    return (
        component == "engine"
        and entries is not None
        and tuple(entries)
        == ENGINE_MCP_L1_CREDENTIAL_PROVENANCE_ARTIFACT_ENTRIES
    )


def is_engine_mcp_execution_plan_sandbox_runtime_slice(component, entries):
    return (
        component == "engine"
        and entries is not None
        and tuple(entries)
        == ENGINE_MCP_EXECUTION_PLAN_SANDBOX_RUNTIME_ARTIFACT_ENTRIES
    )


def is_engine_mcp_gelios_items_envelope_slice(component, entries):
    return (
        component == "engine"
        and entries is not None
        and tuple(entries)
        == ENGINE_MCP_GELIOS_ITEMS_ENVELOPE_ARTIFACT_ENTRIES
    )


def is_engine_mcp_registered_execution_profiles_slice(component, entries):
    return (
        component == "engine"
        and entries is not None
        and tuple(entries)
        == ENGINE_MCP_REGISTERED_EXECUTION_PROFILES_ARTIFACT_ENTRIES
    )


def is_engine_mcp_gelios_units_items_slice(component, entries):
    return (
        component == "engine"
        and entries is not None
        and tuple(entries)
        == ENGINE_MCP_GELIOS_UNITS_ITEMS_ARTIFACT_ENTRIES
    )


def is_engine_agent_full_grant_migration_slice(component, entries):
    return (
        component == "engine"
        and entries is not None
        and tuple(entries) == ENGINE_AGENT_FULL_GRANT_MIGRATION_ARTIFACT_ENTRIES
    )


def is_engine_l2_closed_loop_slice(component, entries):
    return (
        component == "engine"
        and entries is not None
        and tuple(entries) == ENGINE_L2_CLOSED_LOOP_ARTIFACT_ENTRIES
    )


def collect_exact_files(root, entries, label):
    files = {}
    for rel in entries:
        path = root / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(f"{label} path is missing: {rel}")
        if stat.S_ISLNK(path_stat.st_mode):
            die(f"{label} path is unsafe: {rel}")
        if stat.S_ISREG(path_stat.st_mode):
            files[rel] = sha256_file(path)
            continue
        if not stat.S_ISDIR(path_stat.st_mode):
            die(f"{label} path is unsafe: {rel}")
        for child in sorted(path.rglob("*")):
            child_rel = child.relative_to(root).as_posix()
            child_stat = child.lstat()
            if stat.S_ISLNK(child_stat.st_mode):
                die(f"{label} path is unsafe: {child_rel}")
            if stat.S_ISDIR(child_stat.st_mode):
                continue
            if not stat.S_ISREG(child_stat.st_mode):
                die(f"{label} path is unsafe: {child_rel}")
            files[child_rel] = sha256_file(child)
    return files


def collect_engine_data_product_publish_grant_files(root, entries, label):
    files = {}
    for rel in entries:
        path = root / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(f"{label} file is missing: {rel}")
        if stat.S_ISLNK(path_stat.st_mode):
            die(f"{label} path is unsafe: {rel}")
        if stat.S_ISREG(path_stat.st_mode):
            files[rel] = sha256_file(path)
            continue
        if not stat.S_ISDIR(path_stat.st_mode):
            die(f"{label} path is unsafe: {rel}")
        for child in sorted(path.rglob("*")):
            child_rel = child.relative_to(root).as_posix()
            child_stat = child.lstat()
            if stat.S_ISLNK(child_stat.st_mode):
                die(f"{label} path is unsafe: {child_rel}")
            if stat.S_ISDIR(child_stat.st_mode):
                continue
            if not stat.S_ISREG(child_stat.st_mode):
                die(f"{label} path is unsafe: {child_rel}")
            files[child_rel] = sha256_file(child)
    return files


def validate_installed_engine_data_product_publish_grant_foundation(root):
    # The original credential-sink baseline remains immutable. The two route
    # files below became Publish-grant-owned when the initial transition was
    # applied, so their current contract is validated semantically instead of
    # comparing them to their pre-transition bytes.
    publish_owned_predecessors = {
        "nodedc-source/server/routes/engineAgentGateway.js",
        "nodedc-source/server/routes/n8n.js",
    }
    for rel, expected_sha256 in ENGINE_DATA_PRODUCT_PUBLISH_GRANT_INSTALLED_FOUNDATION_SHA256.items():
        if rel in publish_owned_predecessors:
            continue
        path = root / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(f"installed Engine data product publish grant foundation is missing: {rel}")
        if stat.S_ISLNK(path_stat.st_mode) or not stat.S_ISREG(path_stat.st_mode):
            die(f"installed Engine data product publish grant foundation is unsafe: {rel}")
        actual_sha256 = sha256_file(path)
        if actual_sha256 != expected_sha256:
            die(
                "installed Engine data product publish grant foundation drift detected: "
                f"path={rel} expected={expected_sha256} actual={actual_sha256}"
            )

    grant_dir = root / "nodedc-source/server/dataProductPublishGrant"
    try:
        grant_stat = grant_dir.lstat()
    except FileNotFoundError:
        die("installed Engine data product publish grant source is missing")
    if stat.S_ISLNK(grant_stat.st_mode) or not stat.S_ISDIR(grant_stat.st_mode):
        die("installed Engine data product publish grant source is unsafe")
    installed_names = []
    for child in grant_dir.iterdir():
        child_stat = child.lstat()
        if stat.S_ISLNK(child_stat.st_mode) or not stat.S_ISREG(child_stat.st_mode):
            die(f"installed Engine data product publish grant source is unsafe: {child.name}")
        installed_names.append(child.name)
    if tuple(sorted(installed_names)) != ENGINE_DATA_PRODUCT_PUBLISH_GRANT_SOURCE_FILES:
        die("installed Engine data product publish grant source set mismatch")

    required_files = (
        "nodedc-source/server/assets/provider-packages/v1/catalog.json",
        "nodedc-source/server/engineAgents/store.js",
        "nodedc-source/server/routes/engineAgentGateway.js",
        "nodedc-source/server/routes/n8n.js",
        ENGINE_DATA_PRODUCT_PUBLISH_GRANT_OVERRIDE_REL,
    )
    for rel in required_files:
        path = root / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(f"installed Engine data product publish grant file is missing: {rel}")
        if stat.S_ISLNK(path_stat.st_mode) or not stat.S_ISREG(path_stat.st_mode):
            die(f"installed Engine data product publish grant file is unsafe: {rel}")

    try:
        override_text = (root / ENGINE_DATA_PRODUCT_PUBLISH_GRANT_OVERRIDE_REL).read_text(
            encoding="utf-8"
        )
        gateway = (root / "nodedc-source/server/routes/engineAgentGateway.js").read_text(
            encoding="utf-8"
        )
        n8n_route = (root / "nodedc-source/server/routes/n8n.js").read_text(
            encoding="utf-8"
        )
    except (OSError, UnicodeDecodeError):
        die("installed Engine data product publish grant source is unreadable")
    if override_text != expected_engine_data_product_publish_grant_override():
        die("installed Engine data product publish grant override drift detected")
    if "from '../credentialSink/" in n8n_route:
        die("installed Engine data product publish grant depends on the legacy sink")
    for adapter in (
        "engineCredentialSinkN8nAdapter",
        "engineDataProductPublishGrantN8nAdapter",
    ):
        if adapter not in n8n_route:
            die(f"installed Engine data product publish grant adapter is missing: {adapter}")
    for tool in (
        "engine_plan_data_product_publish_grant",
        "engine_apply_data_product_publish_grant",
        "engine_accept_data_product_publish_grant",
        "engine_rollback_data_product_publish_grant",
    ):
        if tool not in gateway:
            die(f"installed Engine data product publish grant tool is missing: {tool}")

    return sha256_file(root / "docker-compose.yml")


def preflight_engine_data_product_publish_grant_predecessor(payload_dir=None):
    root = component_root("engine")
    installed_override = root / ENGINE_DATA_PRODUCT_PUBLISH_GRANT_OVERRIDE_REL
    if installed_override.exists() or installed_override.is_symlink():
        compose_sha256 = validate_installed_engine_data_product_publish_grant_foundation(root)
        if payload_dir is None:
            die("Engine data product publish grant update candidate is required")
        installed_files = collect_engine_data_product_publish_grant_files(
            root,
            ENGINE_DATA_PRODUCT_PUBLISH_GRANT_ARTIFACT_ENTRIES,
            "installed Engine data product publish grant",
        )
        candidate_files = collect_engine_data_product_publish_grant_files(
            payload_dir,
            ENGINE_DATA_PRODUCT_PUBLISH_GRANT_ARTIFACT_ENTRIES,
            "candidate Engine data product publish grant",
        )
        if set(installed_files) != set(candidate_files):
            die("Engine data product publish grant update file set mismatch")
        changed_paths = tuple(sorted(
            rel
            for rel, candidate_sha256 in candidate_files.items()
            if installed_files[rel] != candidate_sha256
        ))
        if not changed_paths:
            die("Engine data product publish grant update contains no source change")
        forbidden_changes = tuple(
            rel
            for rel in changed_paths
            if (
                not rel.startswith(ENGINE_DATA_PRODUCT_PUBLISH_GRANT_SOURCE_PREFIX)
                and rel != ENGINE_PROVIDER_SECURITY_CATALOG_REL
            )
        )
        if forbidden_changes:
            die(
                "Engine data product publish grant update crosses its source boundary: "
                f"path={forbidden_changes[0]}"
            )
        if ENGINE_PROVIDER_SECURITY_CATALOG_REL in changed_paths:
            installed_catalog_sha256 = installed_files[ENGINE_PROVIDER_SECURITY_CATALOG_REL]
            candidate_catalog_sha256 = candidate_files[ENGINE_PROVIDER_SECURITY_CATALOG_REL]
            if (
                installed_catalog_sha256
                != ENGINE_PUBLISH_GRANT_COMPOSITE_PROVIDER_CATALOG_PREDECESSOR_SHA256
                or candidate_catalog_sha256
                != ENGINE_PUBLISH_GRANT_COMPOSITE_PROVIDER_CATALOG_TARGET_SHA256
            ):
                die("Engine composite provider catalog transition mismatch")
            if changed_paths != ENGINE_PUBLISH_GRANT_COMPOSITE_PROVIDER_CHANGED_PATHS:
                die("Engine composite provider update exact changed path set mismatch")
            mode = "installed-composite-provider-update"
        else:
            mode = "installed-source-update"
        return {
            "mode": mode,
            "compose_sha256": compose_sha256,
            "changed_paths": changed_paths,
        }

    actual = {}
    for rel, expected_sha256 in ENGINE_DATA_PRODUCT_PUBLISH_GRANT_PREDECESSOR_SHA256.items():
        path = root / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(f"Engine data product publish grant predecessor file is missing: {rel}")
        if stat.S_ISLNK(path_stat.st_mode) or not stat.S_ISREG(path_stat.st_mode):
            die(f"Engine data product publish grant predecessor file is unsafe: {rel}")
        actual_sha256 = sha256_file(path)
        if actual_sha256 != expected_sha256:
            die(
                "Engine data product publish grant predecessor drift detected: "
                f"path={rel} expected={expected_sha256} actual={actual_sha256}"
            )
        actual[rel] = actual_sha256
    return {
        "mode": "credential-sink-initial-transition",
        "compose_sha256": actual["docker-compose.yml"],
        "changed_paths": (),
    }


def preflight_engine_composite_provider_v4_predecessor():
    root = component_root("engine")
    actual = {}
    for rel, expected_sha256 in ENGINE_COMPOSITE_PROVIDER_V4_PREDECESSOR_SHA256.items():
        path = root / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(f"Engine composite provider v4 predecessor is missing: {rel}")
        if stat.S_ISLNK(path_stat.st_mode) or not stat.S_ISREG(path_stat.st_mode):
            die(f"Engine composite provider v4 predecessor is unsafe: {rel}")
        actual_sha256 = sha256_file(path)
        if actual_sha256 != expected_sha256:
            die(
                "Engine composite provider v4 predecessor drift detected: "
                f"path={rel} expected={expected_sha256} actual={actual_sha256}"
            )
        actual[rel] = actual_sha256
    backend = preflight_engine_credential_backend_runtime()
    if backend["mode"] != "verified-derived-retry":
        die("Engine composite provider v4 requires the active immutable backend")
    return {
        "mode": "exact-composite-provider-v3-to-v4",
        "predecessor_sha256": actual,
        "target_sha256": dict(ENGINE_COMPOSITE_PROVIDER_V4_TARGET_SHA256),
        "backend_mode": backend["mode"],
    }


def preflight_engine_provider_rotating_slot_predecessor():
    root = component_root("engine")
    actual = {}
    for rel, expected_sha256 in ENGINE_PROVIDER_ROTATING_SLOT_PREDECESSOR_SHA256.items():
        path = root / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(f"Engine provider rotating slot predecessor is missing: {rel}")
        if stat.S_ISLNK(path_stat.st_mode) or not stat.S_ISREG(path_stat.st_mode):
            die(f"Engine provider rotating slot predecessor is unsafe: {rel}")
        actual_sha256 = sha256_file(path)
        if actual_sha256 != expected_sha256:
            die(
                "Engine provider rotating slot predecessor drift detected: "
                f"path={rel} expected={expected_sha256} actual={actual_sha256}"
            )
        actual[rel] = actual_sha256
    backend = preflight_engine_credential_backend_runtime()
    if backend["mode"] != "verified-derived-retry":
        die("Engine provider rotating slot requires the active immutable backend")
    return {
        "mode": "exact-gelios-v4-credential-slot-alignment",
        "predecessor_sha256": actual,
        "target_sha256": dict(ENGINE_PROVIDER_ROTATING_SLOT_TARGET_SHA256),
        "backend_mode": backend["mode"],
    }


def preflight_engine_provider_authority_diagnostics_predecessor():
    root = component_root("engine")
    actual = {}
    for rel, expected_sha256 in ENGINE_PROVIDER_AUTHORITY_DIAGNOSTICS_PREDECESSOR_SHA256.items():
        path = root / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(f"Engine provider authority diagnostics predecessor is missing: {rel}")
        if stat.S_ISLNK(path_stat.st_mode) or not stat.S_ISREG(path_stat.st_mode):
            die(f"Engine provider authority diagnostics predecessor is unsafe: {rel}")
        actual_sha256 = sha256_file(path)
        if actual_sha256 != expected_sha256:
            die(
                "Engine provider authority diagnostics predecessor drift detected: "
                f"path={rel} expected={expected_sha256} actual={actual_sha256}"
            )
        actual[rel] = actual_sha256
    backend = preflight_engine_credential_backend_runtime()
    if backend["mode"] != "verified-derived-retry":
        die("Engine provider authority diagnostics requires the active immutable backend")
    return {
        "mode": "private-node-name-reconciliation",
        "predecessor_sha256": actual,
        "target_sha256": dict(ENGINE_PROVIDER_AUTHORITY_DIAGNOSTICS_TARGET_SHA256),
        "backend_mode": backend["mode"],
    }


def preflight_engine_depttrans_zone_authority_v1_predecessor():
    root = component_root("engine")
    actual = {}
    for rel, expected_sha256 in ENGINE_DEPTTRANS_ZONE_AUTHORITY_V1_PREDECESSOR_SHA256.items():
        path = root / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(f"Engine Depttrans zone authority v1 predecessor is missing: {rel}")
        if stat.S_ISLNK(path_stat.st_mode) or not stat.S_ISREG(path_stat.st_mode):
            die(f"Engine Depttrans zone authority v1 predecessor is unsafe: {rel}")
        actual_sha256 = sha256_file(path)
        if actual_sha256 != expected_sha256:
            die(
                "Engine Depttrans zone authority v1 predecessor drift detected: "
                f"path={rel} expected={expected_sha256} actual={actual_sha256}"
            )
        actual[rel] = actual_sha256
    for rel in ENGINE_DEPTTRANS_ZONE_AUTHORITY_V1_NEW_PATHS:
        path = root / rel
        if path.exists() or path.is_symlink():
            die(f"Engine Depttrans zone authority v1 new path already exists: {rel}")
    backend = preflight_engine_credential_backend_runtime()
    if backend["mode"] != "verified-derived-retry":
        die("Engine Depttrans zone authority v1 requires the active immutable backend")
    return {
        "mode": "exact-platform-service-authority-v1",
        "predecessor_sha256": actual,
        "target_sha256": dict(ENGINE_DEPTTRANS_ZONE_AUTHORITY_V1_TARGET_SHA256),
        "backend_mode": backend["mode"],
    }


def print_engine_depttrans_zone_authority_v1_plan(preflight):
    print("engine_provider_authority_transition=platform-service-v1")
    print("engine_provider_package=moscow-department-of-transport.pmd-slow-zones.v1")
    print("engine_provider_id=moscow-department-of-transport")
    print("engine_provider_authority_boundary=platform-service")
    print("engine_provider_platform_service=nodedc-map-gateway")
    print("engine_provider_platform_network=engine")
    print("engine_data_product=map.zones.current.v2")
    print("provider_credential_values=preserved")
    predecessor_sha256 = preflight["predecessor_sha256"]
    target_sha256 = preflight["target_sha256"]
    for changed_path in ENGINE_DEPTTRANS_ZONE_AUTHORITY_V1_ARTIFACT_ENTRIES:
        print(f"engine_depttrans_zone_authority_changed_path={changed_path}")
        if changed_path in predecessor_sha256:
            print(
                f"engine_depttrans_zone_authority_predecessor_sha256[{changed_path}]="
                f"{predecessor_sha256[changed_path]}"
            )
        elif changed_path in ENGINE_DEPTTRANS_ZONE_AUTHORITY_V1_NEW_PATHS:
            print(
                f"engine_depttrans_zone_authority_predecessor_state[{changed_path}]="
                "absent"
            )
        else:
            die(
                "Engine Depttrans zone authority v1 plan has no predecessor state: "
                f"{changed_path}"
            )
        if changed_path not in target_sha256:
            die(
                "Engine Depttrans zone authority v1 plan has no target sha256: "
                f"{changed_path}"
            )
        print(
            f"engine_depttrans_zone_authority_target_sha256[{changed_path}]="
            f"{target_sha256[changed_path]}"
        )
    print(f"backend_current_barrier={preflight['backend_mode']}")
    print("backend_force_recreate=yes")
    print("backend_pull=never")
    print("l2_graph=untouched")
    print("n8n_l1=untouched")
    print("engine_ui=untouched")
    print("engine_databases=untouched")
    print("mcp_nginx=untouched")


def preflight_engine_provider_target_host_policy_predecessor():
    root = component_root("engine")
    actual = {}
    for rel, expected_sha256 in ENGINE_PROVIDER_TARGET_HOST_POLICY_PREDECESSOR_SHA256.items():
        path = root / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(f"Engine provider target host policy predecessor is missing: {rel}")
        if stat.S_ISLNK(path_stat.st_mode) or not stat.S_ISREG(path_stat.st_mode):
            die(f"Engine provider target host policy predecessor is unsafe: {rel}")
        actual_sha256 = sha256_file(path)
        if actual_sha256 != expected_sha256:
            die(
                "Engine provider target host policy predecessor drift detected: "
                f"path={rel} expected={expected_sha256} actual={actual_sha256}"
            )
        actual[rel] = actual_sha256
    backend = preflight_engine_credential_backend_runtime()
    if backend["mode"] != "verified-derived-retry":
        die("Engine provider target host policy requires the active immutable backend")
    return {
        "mode": "exact-provider-literal-target-host",
        "predecessor_sha256": actual,
        "target_sha256": dict(ENGINE_PROVIDER_TARGET_HOST_POLICY_TARGET_SHA256),
        "backend_mode": backend["mode"],
    }


def preflight_engine_mcp_execution_profile_decoder_predecessor():
    root = component_root("engine")
    actual = {}
    for rel, expected_sha256 in (
        ENGINE_MCP_EXECUTION_PROFILE_DECODER_PREDECESSOR_SHA256.items()
    ):
        path = root / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(f"Engine MCP execution profile decoder predecessor is missing: {rel}")
        if stat.S_ISLNK(path_stat.st_mode) or not stat.S_ISREG(path_stat.st_mode):
            die(f"Engine MCP execution profile decoder predecessor is unsafe: {rel}")
        actual_sha256 = sha256_file(path)
        if actual_sha256 != expected_sha256:
            die(
                "Engine MCP execution profile decoder predecessor drift detected: "
                f"path={rel} expected={expected_sha256} actual={actual_sha256}"
            )
        actual[rel] = actual_sha256
    for rel in ENGINE_MCP_EXECUTION_PROFILE_DECODER_NEW_PATHS:
        path = root / rel
        if path.exists() or path.is_symlink():
            die(f"Engine MCP execution profile decoder new path already exists: {rel}")
    backend = preflight_engine_credential_backend_runtime()
    if backend["mode"] != "verified-derived-retry":
        die("Engine MCP execution profile decoder requires the active immutable backend")
    return {
        "mode": "exact-flatted-numeric-string-preservation",
        "predecessor_sha256": actual,
        "target_sha256": dict(ENGINE_MCP_EXECUTION_PROFILE_DECODER_TARGET_SHA256),
        "new_paths": tuple(ENGINE_MCP_EXECUTION_PROFILE_DECODER_NEW_PATHS),
        "backend_mode": backend["mode"],
    }


def preflight_engine_mcp_telemetry_catalog_predecessor():
    root = component_root("engine")
    actual = {}
    for rel, expected_sha256 in ENGINE_MCP_TELEMETRY_CATALOG_PREDECESSOR_SHA256.items():
        path = root / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(f"Engine MCP telemetry catalog predecessor is missing: {rel}")
        if stat.S_ISLNK(path_stat.st_mode) or not stat.S_ISREG(path_stat.st_mode):
            die(f"Engine MCP telemetry catalog predecessor is unsafe: {rel}")
        actual_sha256 = sha256_file(path)
        if actual_sha256 != expected_sha256:
            die(
                "Engine MCP telemetry catalog predecessor drift detected: "
                f"path={rel} expected={expected_sha256} actual={actual_sha256}"
            )
        actual[rel] = actual_sha256
    foundation = {}
    for rel, expected_sha256 in ENGINE_MCP_TELEMETRY_CATALOG_FOUNDATION_SHA256.items():
        path = root / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(f"Engine MCP telemetry catalog foundation is missing: {rel}")
        if (
            stat.S_ISLNK(path_stat.st_mode)
            or not stat.S_ISREG(path_stat.st_mode)
            or sha256_file(path) != expected_sha256
        ):
            die(f"Engine MCP telemetry catalog foundation drift detected: {rel}")
        foundation[rel] = expected_sha256
    for rel in ENGINE_MCP_TELEMETRY_CATALOG_NEW_PATHS:
        path = root / rel
        if path.exists() or path.is_symlink():
            die(f"Engine MCP telemetry catalog new path already exists: {rel}")
    backend = preflight_engine_credential_backend_runtime()
    if backend["mode"] != "verified-derived-retry":
        die("Engine MCP telemetry catalog requires the active immutable backend")
    return {
        "mode": "execution-profile-decoder-v1-to-telemetry-catalog-v1",
        "predecessor_sha256": actual,
        "foundation_sha256": foundation,
        "target_sha256": dict(ENGINE_MCP_TELEMETRY_CATALOG_TARGET_SHA256),
        "new_paths": tuple(ENGINE_MCP_TELEMETRY_CATALOG_NEW_PATHS),
        "backend_mode": backend["mode"],
    }


def preflight_engine_mcp_execution_plan_materialization_predecessor():
    root = component_root("engine")
    actual = {}
    for rel, expected_sha256 in (
        ENGINE_MCP_EXECUTION_PLAN_MATERIALIZATION_PREDECESSOR_SHA256.items()
    ):
        path = root / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(
                "Engine MCP execution plan materialization predecessor is "
                f"missing: {rel}"
            )
        if stat.S_ISLNK(path_stat.st_mode) or not stat.S_ISREG(path_stat.st_mode):
            die(
                "Engine MCP execution plan materialization predecessor is "
                f"unsafe: {rel}"
            )
        actual_sha256 = sha256_file(path)
        if actual_sha256 != expected_sha256:
            die(
                "Engine MCP execution plan materialization predecessor drift "
                f"detected: path={rel} expected={expected_sha256} "
                f"actual={actual_sha256}"
            )
        actual[rel] = actual_sha256
    foundation = {}
    for rel, expected_sha256 in (
        ENGINE_MCP_EXECUTION_PLAN_MATERIALIZATION_FOUNDATION_SHA256.items()
    ):
        path = root / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(
                "Engine MCP execution plan materialization foundation is "
                f"missing: {rel}"
            )
        if (
            stat.S_ISLNK(path_stat.st_mode)
            or not stat.S_ISREG(path_stat.st_mode)
            or sha256_file(path) != expected_sha256
        ):
            die(
                "Engine MCP execution plan materialization foundation drift "
                f"detected: {rel}"
            )
        foundation[rel] = expected_sha256
    for rel in ENGINE_MCP_EXECUTION_PLAN_MATERIALIZATION_NEW_PATHS:
        path = root / rel
        if path.exists() or path.is_symlink():
            die(
                "Engine MCP execution plan materialization new path already "
                f"exists: {rel}"
            )
    backend = preflight_engine_credential_backend_runtime()
    if backend["mode"] != "verified-derived-retry":
        die(
            "Engine MCP execution plan materialization requires the active "
            "immutable backend"
        )
    return {
        "mode": "telemetry-catalog-v1-to-execution-plan-materialization-v1",
        "predecessor_sha256": actual,
        "foundation_sha256": foundation,
        "target_sha256": dict(
            ENGINE_MCP_EXECUTION_PLAN_MATERIALIZATION_TARGET_SHA256
        ),
        "new_paths": tuple(ENGINE_MCP_EXECUTION_PLAN_MATERIALIZATION_NEW_PATHS),
        "backend_mode": backend["mode"],
    }


def preflight_engine_mcp_execution_plan_telemetry_runtime_predecessor():
    root = component_root("engine")
    actual = {}
    for rel, expected_sha256 in (
        ENGINE_MCP_EXECUTION_PLAN_TELEMETRY_RUNTIME_PREDECESSOR_SHA256.items()
    ):
        path = root / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(
                "Engine MCP execution plan telemetry runtime predecessor is "
                f"missing: {rel}"
            )
        if stat.S_ISLNK(path_stat.st_mode) or not stat.S_ISREG(path_stat.st_mode):
            die(
                "Engine MCP execution plan telemetry runtime predecessor is "
                f"unsafe: {rel}"
            )
        actual_sha256 = sha256_file(path)
        if actual_sha256 != expected_sha256:
            die(
                "Engine MCP execution plan telemetry runtime predecessor drift "
                f"detected: path={rel} expected={expected_sha256} "
                f"actual={actual_sha256}"
            )
        actual[rel] = actual_sha256
    foundation = {}
    for rel, expected_sha256 in (
        ENGINE_MCP_EXECUTION_PLAN_TELEMETRY_RUNTIME_FOUNDATION_SHA256.items()
    ):
        path = root / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(
                "Engine MCP execution plan telemetry runtime foundation is "
                f"missing: {rel}"
            )
        if (
            stat.S_ISLNK(path_stat.st_mode)
            or not stat.S_ISREG(path_stat.st_mode)
            or sha256_file(path) != expected_sha256
        ):
            die(
                "Engine MCP execution plan telemetry runtime foundation drift "
                f"detected: {rel}"
            )
        foundation[rel] = expected_sha256
    for rel in ENGINE_MCP_EXECUTION_PLAN_TELEMETRY_RUNTIME_NEW_PATHS:
        path = root / rel
        if path.exists() or path.is_symlink():
            die(
                "Engine MCP execution plan telemetry runtime new path already "
                f"exists: {rel}"
            )
    backend = preflight_engine_credential_backend_runtime()
    if backend["mode"] != "verified-derived-retry":
        die(
            "Engine MCP execution plan telemetry runtime requires the active "
            "immutable backend"
        )
    return {
        "mode": "execution-plan-materialization-v1-to-telemetry-runtime-v2",
        "predecessor_sha256": actual,
        "foundation_sha256": foundation,
        "target_sha256": dict(
            ENGINE_MCP_EXECUTION_PLAN_TELEMETRY_RUNTIME_TARGET_SHA256
        ),
        "new_paths": tuple(
            ENGINE_MCP_EXECUTION_PLAN_TELEMETRY_RUNTIME_NEW_PATHS
        ),
        "backend_mode": backend["mode"],
    }


def preflight_engine_mcp_execution_plan_module_ownership_predecessor():
    root = component_root("engine")
    actual = {}
    for rel, expected_sha256 in (
        ENGINE_MCP_EXECUTION_PLAN_MODULE_OWNERSHIP_PREDECESSOR_SHA256.items()
    ):
        path = root / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(
                "Engine MCP execution plan module ownership predecessor is "
                f"missing: {rel}"
            )
        if stat.S_ISLNK(path_stat.st_mode) or not stat.S_ISREG(path_stat.st_mode):
            die(
                "Engine MCP execution plan module ownership predecessor is "
                f"unsafe: {rel}"
            )
        actual_sha256 = sha256_file(path)
        if actual_sha256 != expected_sha256:
            die(
                "Engine MCP execution plan module ownership predecessor drift "
                f"detected: path={rel} expected={expected_sha256} "
                f"actual={actual_sha256}"
            )
        actual[rel] = actual_sha256
    foundation = {}
    for rel, expected_sha256 in (
        ENGINE_MCP_EXECUTION_PLAN_MODULE_OWNERSHIP_FOUNDATION_SHA256.items()
    ):
        path = root / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(
                "Engine MCP execution plan module ownership foundation is "
                f"missing: {rel}"
            )
        if (
            stat.S_ISLNK(path_stat.st_mode)
            or not stat.S_ISREG(path_stat.st_mode)
            or sha256_file(path) != expected_sha256
        ):
            die(
                "Engine MCP execution plan module ownership foundation drift "
                f"detected: {rel}"
            )
        foundation[rel] = expected_sha256
    for rel in ENGINE_MCP_EXECUTION_PLAN_MODULE_OWNERSHIP_NEW_PATHS:
        path = root / rel
        if path.exists() or path.is_symlink():
            die(
                "Engine MCP execution plan module ownership new path already "
                f"exists: {rel}"
            )
    backend = preflight_engine_credential_backend_runtime()
    if backend["mode"] != "verified-derived-retry":
        die(
            "Engine MCP execution plan module ownership requires the active "
            "immutable backend"
        )
    return {
        "mode":
            "execution-plan-telemetry-runtime-v2-to-module-ownership-v3",
        "predecessor_sha256": actual,
        "foundation_sha256": foundation,
        "target_sha256": dict(
            ENGINE_MCP_EXECUTION_PLAN_MODULE_OWNERSHIP_TARGET_SHA256
        ),
        "new_paths": tuple(
            ENGINE_MCP_EXECUTION_PLAN_MODULE_OWNERSHIP_NEW_PATHS
        ),
        "backend_mode": backend["mode"],
    }


def preflight_engine_mcp_normalized_identity_search_predecessor():
    root = component_root("engine")
    actual = {}
    for rel, expected_sha256 in (
        ENGINE_MCP_NORMALIZED_IDENTITY_SEARCH_PREDECESSOR_SHA256.items()
    ):
        path = root / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(
                "Engine MCP normalized identity search predecessor is "
                f"missing: {rel}"
            )
        if stat.S_ISLNK(path_stat.st_mode) or not stat.S_ISREG(path_stat.st_mode):
            die(
                "Engine MCP normalized identity search predecessor is "
                f"unsafe: {rel}"
            )
        actual_sha256 = sha256_file(path)
        if actual_sha256 != expected_sha256:
            die(
                "Engine MCP normalized identity search predecessor drift "
                f"detected: path={rel} expected={expected_sha256} "
                f"actual={actual_sha256}"
            )
        actual[rel] = actual_sha256

    foundation = {}
    for rel, expected_sha256 in (
        ENGINE_MCP_NORMALIZED_IDENTITY_SEARCH_FOUNDATION_SHA256.items()
    ):
        path = root / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(
                "Engine MCP normalized identity search foundation is "
                f"missing: {rel}"
            )
        if (
            stat.S_ISLNK(path_stat.st_mode)
            or not stat.S_ISREG(path_stat.st_mode)
            or sha256_file(path) != expected_sha256
        ):
            die(
                "Engine MCP normalized identity search foundation drift "
                f"detected: {rel}"
            )
        foundation[rel] = expected_sha256

    for rel in ENGINE_MCP_NORMALIZED_IDENTITY_SEARCH_NEW_PATHS:
        path = root / rel
        if path.exists() or path.is_symlink():
            die(
                "Engine MCP normalized identity search new path already "
                f"exists: {rel}"
            )

    backend = preflight_engine_credential_backend_runtime()
    if backend["mode"] != "verified-derived-retry":
        die(
            "Engine MCP normalized identity search requires the active "
            "immutable backend"
        )
    return {
        "mode": "classified-aspects-v1-to-normalized-identity-search-v1",
        "predecessor_sha256": actual,
        "foundation_sha256": foundation,
        "target_sha256": dict(
            ENGINE_MCP_NORMALIZED_IDENTITY_SEARCH_TARGET_SHA256
        ),
        "new_paths": tuple(ENGINE_MCP_NORMALIZED_IDENTITY_SEARCH_NEW_PATHS),
        "backend_mode": backend["mode"],
    }


def preflight_engine_mcp_l1_credential_reuse_predecessor():
    root = component_root("engine")
    actual = {}
    for rel, expected_sha256 in (
        ENGINE_MCP_L1_CREDENTIAL_REUSE_PREDECESSOR_SHA256.items()
    ):
        path = root / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(f"Engine MCP L1 credential reuse predecessor is missing: {rel}")
        if stat.S_ISLNK(path_stat.st_mode) or not stat.S_ISREG(path_stat.st_mode):
            die(f"Engine MCP L1 credential reuse predecessor is unsafe: {rel}")
        actual_sha256 = sha256_file(path)
        if actual_sha256 != expected_sha256:
            die(
                "Engine MCP L1 credential reuse predecessor drift detected: "
                f"path={rel} expected={expected_sha256} actual={actual_sha256}"
            )
        actual[rel] = actual_sha256

    foundation = {}
    for rel, expected_sha256 in (
        ENGINE_MCP_L1_CREDENTIAL_REUSE_FOUNDATION_SHA256.items()
    ):
        path = root / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(f"Engine MCP L1 credential reuse foundation is missing: {rel}")
        if (
            stat.S_ISLNK(path_stat.st_mode)
            or not stat.S_ISREG(path_stat.st_mode)
            or sha256_file(path) != expected_sha256
        ):
            die(f"Engine MCP L1 credential reuse foundation drift detected: {rel}")
        foundation[rel] = expected_sha256

    for rel in ENGINE_MCP_L1_CREDENTIAL_REUSE_NEW_PATHS:
        path = root / rel
        if path.exists() or path.is_symlink():
            die(
                "Engine MCP L1 credential reuse new path already exists: "
                f"{rel}"
            )

    backend = preflight_engine_credential_backend_runtime()
    if backend["mode"] != "verified-derived-retry":
        die(
            "Engine MCP L1 credential reuse requires the active immutable "
            "backend"
        )
    return {
        "mode": "normalized-identity-search-v1-to-l1-credential-reuse-v1",
        "predecessor_sha256": actual,
        "foundation_sha256": foundation,
        "target_sha256": dict(ENGINE_MCP_L1_CREDENTIAL_REUSE_TARGET_SHA256),
        "new_paths": tuple(ENGINE_MCP_L1_CREDENTIAL_REUSE_NEW_PATHS),
        "backend_mode": backend["mode"],
    }


def preflight_engine_mcp_l1_credential_provenance_predecessor():
    root = component_root("engine")
    actual = {}
    for rel, expected_sha256 in (
        ENGINE_MCP_L1_CREDENTIAL_PROVENANCE_PREDECESSOR_SHA256.items()
    ):
        path = root / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(
                "Engine MCP L1 credential provenance predecessor is missing: "
                f"{rel}"
            )
        if stat.S_ISLNK(path_stat.st_mode) or not stat.S_ISREG(path_stat.st_mode):
            die(
                "Engine MCP L1 credential provenance predecessor is unsafe: "
                f"{rel}"
            )
        actual_sha256 = sha256_file(path)
        if actual_sha256 != expected_sha256:
            die(
                "Engine MCP L1 credential provenance predecessor drift "
                f"detected: path={rel} expected={expected_sha256} "
                f"actual={actual_sha256}"
            )
        actual[rel] = actual_sha256

    foundation = {}
    for rel, expected_sha256 in (
        ENGINE_MCP_L1_CREDENTIAL_PROVENANCE_FOUNDATION_SHA256.items()
    ):
        path = root / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(
                "Engine MCP L1 credential provenance foundation is missing: "
                f"{rel}"
            )
        if (
            stat.S_ISLNK(path_stat.st_mode)
            or not stat.S_ISREG(path_stat.st_mode)
            or sha256_file(path) != expected_sha256
        ):
            die(
                "Engine MCP L1 credential provenance foundation drift "
                f"detected: {rel}"
            )
        foundation[rel] = expected_sha256

    for rel in ENGINE_MCP_L1_CREDENTIAL_PROVENANCE_NEW_PATHS:
        path = root / rel
        if path.exists() or path.is_symlink():
            die(
                "Engine MCP L1 credential provenance new path already exists: "
                f"{rel}"
            )

    backend = preflight_engine_credential_backend_runtime()
    if backend["mode"] != "verified-derived-retry":
        die(
            "Engine MCP L1 credential provenance requires the active "
            "immutable backend"
        )
    return {
        "mode": "l1-credential-reuse-v1-to-provenance-v2",
        "predecessor_sha256": actual,
        "foundation_sha256": foundation,
        "target_sha256": dict(
            ENGINE_MCP_L1_CREDENTIAL_PROVENANCE_TARGET_SHA256
        ),
        "new_paths": tuple(ENGINE_MCP_L1_CREDENTIAL_PROVENANCE_NEW_PATHS),
        "backend_mode": backend["mode"],
    }


def preflight_engine_mcp_execution_plan_sandbox_runtime_predecessor():
    root = component_root("engine")
    actual = {}
    for rel, expected_sha256 in (
        ENGINE_MCP_EXECUTION_PLAN_SANDBOX_RUNTIME_PREDECESSOR_SHA256.items()
    ):
        path = root / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(
                "Engine MCP execution plan sandbox runtime predecessor is "
                f"missing: {rel}"
            )
        if stat.S_ISLNK(path_stat.st_mode) or not stat.S_ISREG(path_stat.st_mode):
            die(
                "Engine MCP execution plan sandbox runtime predecessor is "
                f"unsafe: {rel}"
            )
        actual_sha256 = sha256_file(path)
        if actual_sha256 != expected_sha256:
            die(
                "Engine MCP execution plan sandbox runtime predecessor drift "
                f"detected: path={rel} expected={expected_sha256} "
                f"actual={actual_sha256}"
            )
        actual[rel] = actual_sha256

    foundation = {}
    for rel, expected_sha256 in (
        ENGINE_MCP_EXECUTION_PLAN_SANDBOX_RUNTIME_FOUNDATION_SHA256.items()
    ):
        path = root / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(
                "Engine MCP execution plan sandbox runtime foundation is "
                f"missing: {rel}"
            )
        if (
            stat.S_ISLNK(path_stat.st_mode)
            or not stat.S_ISREG(path_stat.st_mode)
            or sha256_file(path) != expected_sha256
        ):
            die(
                "Engine MCP execution plan sandbox runtime foundation drift "
                f"detected: {rel}"
            )
        foundation[rel] = expected_sha256

    for rel in ENGINE_MCP_EXECUTION_PLAN_SANDBOX_RUNTIME_NEW_PATHS:
        path = root / rel
        if path.exists() or path.is_symlink():
            die(
                "Engine MCP execution plan sandbox runtime new path already "
                f"exists: {rel}"
            )

    backend = preflight_engine_credential_backend_runtime()
    if backend["mode"] != "verified-derived-retry":
        die(
            "Engine MCP execution plan sandbox runtime requires the active "
            "immutable backend"
        )
    return {
        "mode": "l1-credential-provenance-v2-to-sandbox-runtime-v4",
        "predecessor_sha256": actual,
        "foundation_sha256": foundation,
        "target_sha256": dict(
            ENGINE_MCP_EXECUTION_PLAN_SANDBOX_RUNTIME_TARGET_SHA256
        ),
        "new_paths": tuple(
            ENGINE_MCP_EXECUTION_PLAN_SANDBOX_RUNTIME_NEW_PATHS
        ),
        "backend_mode": backend["mode"],
    }


def preflight_engine_mcp_gelios_items_envelope_predecessor():
    root = component_root("engine")
    actual = {}
    for rel, expected_sha256 in (
        ENGINE_MCP_GELIOS_ITEMS_ENVELOPE_PREDECESSOR_SHA256.items()
    ):
        path = root / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(f"Engine MCP Gelios items envelope predecessor is missing: {rel}")
        if stat.S_ISLNK(path_stat.st_mode) or not stat.S_ISREG(path_stat.st_mode):
            die(f"Engine MCP Gelios items envelope predecessor is unsafe: {rel}")
        actual_sha256 = sha256_file(path)
        if actual_sha256 != expected_sha256:
            die(
                "Engine MCP Gelios items envelope predecessor drift detected: "
                f"path={rel} expected={expected_sha256} actual={actual_sha256}"
            )
        actual[rel] = actual_sha256

    foundation = {}
    for rel, expected_sha256 in (
        ENGINE_MCP_GELIOS_ITEMS_ENVELOPE_FOUNDATION_SHA256.items()
    ):
        path = root / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(f"Engine MCP Gelios items envelope foundation is missing: {rel}")
        if (
            stat.S_ISLNK(path_stat.st_mode)
            or not stat.S_ISREG(path_stat.st_mode)
            or sha256_file(path) != expected_sha256
        ):
            die(f"Engine MCP Gelios items envelope foundation drift: {rel}")
        foundation[rel] = expected_sha256

    for rel in ENGINE_MCP_GELIOS_ITEMS_ENVELOPE_NEW_PATHS:
        path = root / rel
        if path.exists() or path.is_symlink():
            die(
                "Engine MCP Gelios items envelope new path already exists: "
                f"{rel}"
            )

    backend = preflight_engine_credential_backend_runtime()
    if backend["mode"] != "verified-derived-retry":
        die(
            "Engine MCP Gelios items envelope requires the active immutable "
            "backend"
        )
    return {
        "mode": "gelios-provider-v11-to-v12-items-envelope",
        "predecessor_sha256": actual,
        "foundation_sha256": foundation,
        "target_sha256": dict(
            ENGINE_MCP_GELIOS_ITEMS_ENVELOPE_TARGET_SHA256
        ),
        "new_paths": tuple(ENGINE_MCP_GELIOS_ITEMS_ENVELOPE_NEW_PATHS),
        "backend_mode": backend["mode"],
    }


def preflight_engine_mcp_registered_execution_profiles_predecessor():
    root = component_root("engine")
    actual = {}
    for rel, expected_sha256 in (
        ENGINE_MCP_REGISTERED_EXECUTION_PROFILES_PREDECESSOR_SHA256.items()
    ):
        path = root / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(
                "Engine MCP registered execution profiles predecessor is "
                f"missing: {rel}"
            )
        if stat.S_ISLNK(path_stat.st_mode) or not stat.S_ISREG(path_stat.st_mode):
            die(
                "Engine MCP registered execution profiles predecessor is "
                f"unsafe: {rel}"
            )
        actual_sha256 = sha256_file(path)
        if actual_sha256 != expected_sha256:
            die(
                "Engine MCP registered execution profiles predecessor drift "
                f"detected: path={rel} expected={expected_sha256} "
                f"actual={actual_sha256}"
            )
        actual[rel] = actual_sha256

    foundation = {}
    for rel, expected_sha256 in (
        ENGINE_MCP_REGISTERED_EXECUTION_PROFILES_FOUNDATION_SHA256.items()
    ):
        path = root / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(
                "Engine MCP registered execution profiles foundation is "
                f"missing: {rel}"
            )
        if (
            stat.S_ISLNK(path_stat.st_mode)
            or not stat.S_ISREG(path_stat.st_mode)
            or sha256_file(path) != expected_sha256
        ):
            die(
                "Engine MCP registered execution profiles foundation drift: "
                f"{rel}"
            )
        foundation[rel] = expected_sha256

    for rel in (
        *ENGINE_MCP_REGISTERED_EXECUTION_PROFILES_NEW_PATHS,
        *ENGINE_MCP_REGISTERED_EXECUTION_PROFILES_FAILED_PATHS,
    ):
        path = root / rel
        if path.exists() or path.is_symlink():
            die(
                "Engine MCP registered execution profiles new path already "
                f"exists: {rel}"
            )

    backend = preflight_engine_credential_backend_runtime()
    if backend["mode"] != "verified-derived-retry":
        die(
            "Engine MCP registered execution profiles requires the active "
            "immutable backend"
        )
    return {
        "mode":
            "gelios-items-envelope-v12-to-registered-profiles-v2-attested",
        "predecessor_sha256": actual,
        "foundation_sha256": foundation,
        "target_sha256": dict(
            ENGINE_MCP_REGISTERED_EXECUTION_PROFILES_TARGET_SHA256
        ),
        "new_paths": tuple(
            ENGINE_MCP_REGISTERED_EXECUTION_PROFILES_NEW_PATHS
        ),
        "backend_mode": backend["mode"],
    }


def preflight_engine_mcp_gelios_units_items_predecessor():
    root = component_root("engine")
    actual = {}
    for rel, expected_sha256 in (
        ENGINE_MCP_GELIOS_UNITS_ITEMS_PREDECESSOR_SHA256.items()
    ):
        path = root / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(
                "Engine MCP Gelios units items predecessor is missing: "
                f"{rel}"
            )
        if stat.S_ISLNK(path_stat.st_mode) or not stat.S_ISREG(path_stat.st_mode):
            die(f"Engine MCP Gelios units items predecessor is unsafe: {rel}")
        actual_sha256 = sha256_file(path)
        if actual_sha256 != expected_sha256:
            die(
                "Engine MCP Gelios units items predecessor drift detected: "
                f"path={rel} expected={expected_sha256} "
                f"actual={actual_sha256}"
            )
        actual[rel] = actual_sha256

    foundation = {}
    for rel, expected_sha256 in (
        ENGINE_MCP_GELIOS_UNITS_ITEMS_FOUNDATION_SHA256.items()
    ):
        path = root / rel
        try:
            path_stat = path.lstat()
        except FileNotFoundError:
            die(
                "Engine MCP Gelios units items foundation is missing: "
                f"{rel}"
            )
        if (
            stat.S_ISLNK(path_stat.st_mode)
            or not stat.S_ISREG(path_stat.st_mode)
            or sha256_file(path) != expected_sha256
        ):
            die(f"Engine MCP Gelios units items foundation drift: {rel}")
        foundation[rel] = expected_sha256

    for rel in ENGINE_MCP_GELIOS_UNITS_ITEMS_NEW_PATHS:
        path = root / rel
        if path.exists() or path.is_symlink():
            die(
                "Engine MCP Gelios units items new path already exists: "
                f"{rel}"
            )

    backend = preflight_engine_credential_backend_runtime()
    if backend["mode"] != "verified-derived-retry":
        die(
            "Engine MCP Gelios units items requires the active immutable "
            "backend"
        )
    return {
        "mode":
            "registered-profiles-v2-to-gelios-v12.0.1-units-items-envelope",
        "predecessor_sha256": actual,
        "foundation_sha256": foundation,
        "target_sha256": dict(
            ENGINE_MCP_GELIOS_UNITS_ITEMS_TARGET_SHA256
        ),
        "new_paths": tuple(ENGINE_MCP_GELIOS_UNITS_ITEMS_NEW_PATHS),
        "backend_mode": backend["mode"],
    }


def preflight_engine_agent_full_grant_migration_predecessor():
    root = component_root("engine")
    store_path = root / ENGINE_AGENT_FULL_GRANT_MIGRATION_STORE_REL
    try:
        store_stat = store_path.lstat()
    except FileNotFoundError:
        die("Engine agent full grant migration predecessor is missing")
    if stat.S_ISLNK(store_stat.st_mode) or not stat.S_ISREG(store_stat.st_mode):
        die("Engine agent full grant migration predecessor is unsafe")
    actual_sha256 = sha256_file(store_path)
    if actual_sha256 != ENGINE_AGENT_FULL_GRANT_MIGRATION_PREDECESSOR_SHA256:
        die(
            "Engine agent full grant migration predecessor drift detected: "
            f"expected={ENGINE_AGENT_FULL_GRANT_MIGRATION_PREDECESSOR_SHA256} "
            f"actual={actual_sha256}"
        )

    publish_override = root / ENGINE_DATA_PRODUCT_PUBLISH_GRANT_OVERRIDE_REL
    try:
        publish_stat = publish_override.lstat()
        publish_text = publish_override.read_text(encoding="utf-8")
    except (FileNotFoundError, OSError, UnicodeDecodeError):
        die("Engine agent full grant migration requires the installed Publish overlay")
    if (
        stat.S_ISLNK(publish_stat.st_mode)
        or not stat.S_ISREG(publish_stat.st_mode)
        or publish_text != expected_engine_data_product_publish_grant_override()
    ):
        die("Engine agent full grant migration Publish overlay mismatch")
    return actual_sha256


def is_platform_provider_catalog_only(entries):
    prefix = "platform/packages/external-provider-contract/providers/"
    return bool(entries) and all(rel.startswith(prefix) for rel in entries)


def component_services(component, entries=None):
    if is_device_plane_postgres_bootstrap_slice(component, entries):
        # This exact one-time transition is the only Device Plane artifact that
        # may select durable state. Its preflight requires both container and
        # named volume to be absent, so --force-recreate cannot touch an
        # installed database.
        return ("device-postgres",)

    if is_engine_l2_closed_loop_slice(component, entries):
        # The failed 030 apply published both the backend source and the built
        # UI before Compose rejected the descriptor/source mismatch.  The exact
        # reconciliation transition must therefore activate both generations.
        return ("nodedc-backend", "app")

    if (
        is_engine_mcp_control_plane_slice(component, entries)
        or is_engine_mcp_ontology_sdk_slice(component, entries)
        or is_engine_mcp_autonomy_provider_v5_slice(component, entries)
        or is_engine_composite_provider_v4_slice(component, entries)
        or is_engine_provider_rotating_slot_slice(component, entries)
        or is_engine_provider_authority_diagnostics_slice(component, entries)
        or is_engine_depttrans_zone_authority_v1_slice(component, entries)
        or is_engine_provider_target_host_policy_slice(component, entries)
        or is_engine_mcp_execution_profile_decoder_slice(component, entries)
        or is_engine_mcp_telemetry_catalog_slice(component, entries)
        or is_engine_mcp_execution_plan_materialization_slice(component, entries)
        or is_engine_mcp_execution_plan_telemetry_runtime_slice(component, entries)
        or is_engine_mcp_execution_plan_module_ownership_slice(component, entries)
        or is_engine_mcp_normalized_identity_search_slice(component, entries)
        or is_engine_mcp_l1_credential_reuse_slice(component, entries)
        or is_engine_mcp_l1_credential_provenance_slice(component, entries)
        or is_engine_mcp_execution_plan_sandbox_runtime_slice(component, entries)
        or is_engine_mcp_gelios_items_envelope_slice(component, entries)
        or is_engine_mcp_registered_execution_profiles_slice(component, entries)
        or is_engine_mcp_gelios_units_items_slice(component, entries)
        or is_engine_provider_security_catalog_slice(component, entries)
    ):
        # This slice updates only the existing Engine backend control plane.
        # Node intelligence keeps the same immutable sidecar image and n8n/L1
        # retain their current generations.
        return ("nodedc-backend",)

    if is_engine_node_intelligence_transition(component, entries):
        if tuple(entries) == ENGINE_NODE_INTELLIGENCE_ARTIFACT_ENTRIES:
            return (ENGINE_NODE_INTELLIGENCE_SERVICE, "nodedc-backend")
        return ("nodedc-backend",)

    if is_engine_n8n_transition(component, entries):
        # The actual Engine topology has one n8n process and no separately
        # deployed worker/webhook services.  The release barrier therefore
        # force-recreates exactly this service and never touches its database.
        return ("n8n",)

    if touches_engine_credential_sink(component, entries):
        # The sink is served by the existing Engine backend. It has no frontend
        # or n8n process code, so preserve those generations during this slice.
        return ("nodedc-backend",)
    if is_engine_data_product_publish_grant_slice(component, entries):
        # Publish-grant source and its fixed runtime overlay are backend-owned.
        # n8n, the UI and every database retain their existing generations.
        return ("nodedc-backend",)
    if is_engine_agent_full_grant_migration_slice(component, entries):
        # This one-time compatibility migration changes only Engine Agent
        # authorization normalization inside the already-active backend.
        return ("nodedc-backend",)

    if component == "device-plane" and entries is not None:
        selected = []

        def add(*services):
            for service in services:
                if service not in selected:
                    selected.append(service)

        touches_common = any(
            rel in (
                ".dockerignore",
                "package.json",
                "package-lock.json",
                "docker-compose.device-plane.yml",
                "packages/device-protocol-contract",
                "packages/arusnavi-b2-adapter",
            )
            or rel.startswith((
                "packages/device-protocol-contract/",
                "packages/arusnavi-b2-adapter/",
            ))
            for rel in entries
        )
        touches_core = any(
            rel == "services/device-control-core"
            or rel.startswith("services/device-control-core/")
            for rel in entries
        )
        touches_gateway = any(
            rel == "services/device-gateway"
            or rel.startswith("services/device-gateway/")
            for rel in entries
        )
        if touches_common or touches_core:
            add("device-control-core")
        if touches_common or touches_gateway:
            add("device-gateway")
        return tuple(selected)

    if component == "dc-cms" and entries is not None:
        selected = []

        def add(*services):
            for service in services:
                if service not in selected:
                    selected.append(service)

        touches_compose = any(rel == "infra/docker-compose.yml" for rel in entries)
        touches_proxy = any(rel == "infra/reverse-proxy" or rel.startswith("infra/reverse-proxy/") for rel in entries)
        touches_authentik = any(rel == "infra/authentik" or rel.startswith("infra/authentik/") for rel in entries)
        touches_app = any(
            rel in ("Dockerfile", "package.json", "package-lock.json", "README.md")
            or rel.startswith(("admin/", "projects/", "server/"))
            for rel in entries
        )

        if touches_compose:
            return COMPONENTS[component]["services"]
        if touches_authentik:
            add("postgresql-authentik", "authentik-server", "authentik-worker", "authentik-bootstrap", "cms-app", "reverse-proxy")
        if touches_app:
            add("cms-app")
        if touches_proxy:
            add("reverse-proxy")
        if selected:
            return tuple(selected)

    if component == "tasker" and entries is not None:
        selected = ["api", "worker", "beat-worker", "web"]
        touches_compose = any(
            rel in ("plane-app/docker-compose.yaml", "plane-app/docker-compose.synology.override.yml")
            for rel in entries
        )
        touches_proxy = any(rel == "plane-src/apps/proxy/Caddyfile.ce" for rel in entries)
        if touches_compose or touches_proxy:
            selected.append("proxy")
        return tuple(selected)

    if component == "platform" and entries is not None:
        if is_platform_provider_catalog_only(entries):
            return ()
        selected = []

        def add(*services):
            for service in services:
                if service not in selected:
                    selected.append(service)

        touches_compose = any(rel == "platform/docker-compose.platform-http.yml" for rel in entries)
        touches_caddy = any(rel == "platform/Caddyfile.http" for rel in entries)
        touches_notification = any(rel == "platform/notification-core" or rel.startswith("platform/notification-core/") for rel in entries)
        touches_ai_workspace = any(rel == "platform/ai-workspace-hub" or rel.startswith("platform/ai-workspace-hub/") for rel in entries)
        touches_ai_workspace_assistant = any(rel == "platform/ai-workspace-assistant" or rel.startswith("platform/ai-workspace-assistant/") for rel in entries)
        touches_ontology = any(rel == "platform/ontology-core" or rel.startswith("platform/ontology-core/") for rel in entries)
        touches_gelios = any(rel == "platform/gelios-gateway" or rel.startswith("platform/gelios-gateway/") for rel in entries)
        touches_map_gateway = any(rel == "platform/services/map-gateway" or rel.startswith("platform/services/map-gateway/") for rel in entries)
        touches_external_data_plane = touches_external_data_plane_files(entries)
        touches_authentik = any(rel == "authentik/custom-templates" or rel.startswith("authentik/custom-templates/") for rel in entries)
        map_gateway_only_compose = touches_compose and touches_map_gateway and not any((touches_notification, touches_ai_workspace, touches_ai_workspace_assistant, touches_ontology, touches_gelios, touches_external_data_plane, touches_authentik))
        restart_all_for_compose = touches_compose and not map_gateway_only_compose

        if touches_notification or restart_all_for_compose:
            add("notification-postgres", "notification-core", "launcher", "reverse-proxy")
        if touches_ai_workspace or restart_all_for_compose:
            add("ai-workspace-hub", "reverse-proxy")
        if touches_ai_workspace_assistant or restart_all_for_compose:
            add("ai-workspace-postgres", "ai-workspace-assistant")
        if touches_ontology or restart_all_for_compose:
            add("ontology-core", "ai-workspace-hub")
        if touches_gelios or restart_all_for_compose:
            add("gelios-postgres", "gelios-gateway")
        if touches_map_gateway:
            add("map-gateway")
        if touches_external_data_plane:
            # The Timescale/PostgreSQL service is durable infrastructure. Both
            # contract and managed EDP changes recreate only the EDP
            # application process.
            add("external-data-plane")
        if touches_authentik:
            add("authentik-server", "authentik-worker", "reverse-proxy")
        if touches_caddy:
            add("reverse-proxy")

        if selected:
            return tuple(selected)

    return COMPONENTS[component]["services"]


def component_compose_no_deps(component, entries=None):
    if component == "dc-cms" and entries is not None:
        touches_compose = any(rel == "infra/docker-compose.yml" for rel in entries)
        touches_proxy = any(rel == "infra/reverse-proxy" or rel.startswith("infra/reverse-proxy/") for rel in entries)
        touches_authentik = any(rel == "infra/authentik" or rel.startswith("infra/authentik/") for rel in entries)
        return not (touches_compose or touches_proxy or touches_authentik)

    return bool(COMPONENTS[component].get("compose_no_deps"))


def engine_backend_immutable_runtime_is_current():
    metadata = validate_engine_backend_activation_marker()
    compose_project = component_compose_root("engine").name
    result = subprocess.run(
        [
            str(DOCKER), "container", "ls", "-a",
            "--filter", f"label=com.docker.compose.project={compose_project}",
            "--filter", "label=com.docker.compose.service=nodedc-backend",
            "--format", "{{.ID}}",
        ],
        check=False,
        capture_output=True,
        text=True,
    )
    container_ids = [line.strip() for line in result.stdout.splitlines() if line.strip()]
    if (result.returncode != 0
            or len(container_ids) != 1
            or not re.fullmatch(r"[a-f0-9]{12,64}", container_ids[0])):
        die("Engine backend immutable runtime topology is unproven")
    containers = docker_json(
        ["container", "inspect", container_ids[0]],
        "Engine backend immutable runtime container inspect",
    )
    container = containers[0] if isinstance(containers, list) and len(containers) == 1 else None
    image = inspect_engine_backend_derived_image(metadata)
    return (
        isinstance(container, dict)
        and container.get("Image") == image.get("Id")
        and (container.get("Config") or {}).get("Image") == ENGINE_CREDENTIAL_BACKEND_IMAGE
    )


def component_compose_files(
    component,
    allow_prepared_engine_backend=False,
    expected_node_intelligence_gateway_sha256=None,
):
    if component == "engine":
        root = component_root(component)
        files = [root / "docker-compose.yml"]
        descriptor = current_engine_n8n_transition_descriptor()
        if descriptor and descriptor["action"] == "activate":
            override = root / ENGINE_N8N_COMPOSE_OVERRIDE_REL
            if override.is_symlink() or not override.is_file():
                die("active Engine n8n Compose override is missing or unsafe")
            try:
                override_text = override.read_text(encoding="utf-8")
            except (OSError, UnicodeDecodeError):
                die("active Engine n8n Compose override cannot be read")
            if override_text != expected_engine_n8n_compose_override(descriptor):
                die("installed Engine n8n Compose override drift detected")
            files.append(override)
        if (ENGINE_CREDENTIAL_BACKEND_ACTIVATION_FILE.exists()
                or ENGINE_CREDENTIAL_BACKEND_ACTIVATION_FILE.is_symlink()):
            validate_engine_backend_activation_marker()
            if (allow_prepared_engine_backend
                    or engine_backend_immutable_runtime_is_current()):
                files.append(ENGINE_CREDENTIAL_BACKEND_OVERRIDE_FILE)
        publish_grant_override = root / ENGINE_DATA_PRODUCT_PUBLISH_GRANT_OVERRIDE_REL
        if publish_grant_override.exists() or publish_grant_override.is_symlink():
            if publish_grant_override.is_symlink() or not publish_grant_override.is_file():
                die("installed Engine data product publish grant override is unsafe")
            try:
                publish_grant_override_text = publish_grant_override.read_text(encoding="utf-8")
            except (OSError, UnicodeDecodeError):
                die("installed Engine data product publish grant override cannot be read")
            if publish_grant_override_text != expected_engine_data_product_publish_grant_override():
                die("installed Engine data product publish grant override drift detected")
            # Canonical order is immutable: base, active L2 extension, credential
            # sink, then the additive Publish grant overlay.
            files.append(publish_grant_override)
        read_grant_override = root / ENGINE_DATA_PRODUCT_READ_GRANT_OVERRIDE_REL
        if read_grant_override.exists() or read_grant_override.is_symlink():
            if read_grant_override.is_symlink() or not read_grant_override.is_file():
                die("installed Engine data product read grant override is unsafe")
            try:
                read_grant_override_text = read_grant_override.read_text(encoding="utf-8")
            except (OSError, UnicodeDecodeError):
                die("installed Engine data product read grant override cannot be read")
            if read_grant_override_text != expected_engine_data_product_read_grant_override():
                die("installed Engine data product read grant override drift detected")
            # Read authority is additive and ordered after the writer/private-key overlay.
            files.append(read_grant_override)
        node_intelligence_descriptor = current_engine_node_intelligence_descriptor()
        if (
            node_intelligence_descriptor is not None
            and node_intelligence_descriptor["action"] == "activate"
        ):
            if expected_node_intelligence_gateway_sha256 is None:
                validate_installed_engine_node_intelligence_source(
                    node_intelligence_descriptor
                )
            else:
                validate_installed_engine_node_intelligence_source(
                    node_intelligence_descriptor,
                    expected_gateway_sha256=
                        expected_node_intelligence_gateway_sha256,
                )
            files.append(root / ENGINE_NODE_INTELLIGENCE_OVERRIDE_REL)
        return tuple(files)
    files = COMPONENTS[component].get("compose_files", ())
    if component == "platform":
        # The EDP overlay is optional until its first dedicated artifact lands.
        # Once installed (or after a candidate has been copied), it participates
        # in every authoritative Compose operation.
        files = tuple(
            path
            for path in files
            if path.name != Path(PLATFORM_EXTERNAL_DATA_PLANE_COMPOSE_REL).name or path.is_file()
        )
    return files


def component_compose_env_file(component):
    return COMPONENTS[component].get("compose_env_file")


def component_build_root(component):
    return COMPONENTS[component].get("build_root")


def component_build_args(component, entries=None):
    if component == "platform" and entries is not None:
        touches_notification = any(rel == "platform/notification-core" or rel.startswith("platform/notification-core/") for rel in entries)
        return COMPONENTS[component].get("build") if touches_notification else None

    if component == "bim-viewer" and entries is not None:
        touches_converter = any(rel == "converter" or rel.startswith("converter/") for rel in entries)
        return COMPONENTS[component].get("build") if touches_converter else None

    return COMPONENTS[component].get("build")


def component_builds(component, entries=None):
    if is_device_plane_postgres_bootstrap_slice(component, entries):
        return ()

    if component == "device-plane" and entries is not None:
        selected_services = component_services(component, entries)
        builds = []
        if "device-control-core" in selected_services:
            builds.append((
                DEVICE_PLANE_ROOT,
                (
                    "build",
                    "--no-cache",
                    "--network=host",
                    "-f",
                    "services/device-control-core/Dockerfile",
                    "-t",
                    DEVICE_PLANE_CONTROL_CORE_IMAGE,
                    ".",
                ),
            ))
        if "device-gateway" in selected_services:
            builds.append((
                DEVICE_PLANE_ROOT,
                (
                    "build",
                    "--no-cache",
                    "--network=host",
                    "-f",
                    "services/device-gateway/Dockerfile",
                    "-t",
                    DEVICE_PLANE_GATEWAY_IMAGE,
                    ".",
                ),
            ))
        return tuple(builds)

    if component == "platform" and entries is not None:
        touches_compose = any(rel == "platform/docker-compose.platform-http.yml" for rel in entries)
        touches_notification = any(rel == "platform/notification-core" or rel.startswith("platform/notification-core/") for rel in entries)
        touches_ai_workspace = any(rel == "platform/ai-workspace-hub" or rel.startswith("platform/ai-workspace-hub/") for rel in entries)
        touches_ai_workspace_assistant = any(rel == "platform/ai-workspace-assistant" or rel.startswith("platform/ai-workspace-assistant/") for rel in entries)
        touches_ontology = any(rel == "platform/ontology-core" or rel.startswith("platform/ontology-core/") for rel in entries)
        touches_gelios = any(rel == "platform/gelios-gateway" or rel.startswith("platform/gelios-gateway/") for rel in entries)
        touches_map_gateway = any(rel == "platform/services/map-gateway" or rel.startswith("platform/services/map-gateway/") for rel in entries)
        touches_external_data_plane = touches_external_data_plane_files(entries)
        map_gateway_only_compose = touches_compose and touches_map_gateway and not any((touches_notification, touches_ai_workspace, touches_ai_workspace_assistant, touches_ontology, touches_gelios, touches_external_data_plane))
        rebuild_all_for_compose = touches_compose and not map_gateway_only_compose
        builds = []
        if touches_notification or rebuild_all_for_compose:
            builds.append((
                Path("/volume1/docker/nodedc-platform/platform/notification-core"),
                ("build", "--no-cache", "-t", "nodedc/notification-core:local", "."),
            ))
        if touches_ai_workspace or rebuild_all_for_compose:
            builds.append((
                Path("/volume1/docker/nodedc-platform/platform/ai-workspace-hub"),
                ("build", "--no-cache", "-t", "nodedc/ai-workspace-hub:local", "."),
            ))
        if touches_ai_workspace_assistant or rebuild_all_for_compose:
            builds.append((
                Path("/volume1/docker/nodedc-platform/platform/ai-workspace-assistant"),
                ("build", "--no-cache", "-t", "nodedc/ai-workspace-assistant:local", "."),
            ))
        if touches_ontology or rebuild_all_for_compose:
            builds.append((
                Path("/volume1/docker/nodedc-platform/platform/ontology-core"),
                ("build", "--no-cache", "-t", "nodedc/ontology-core:local", "."),
            ))
        if touches_gelios or rebuild_all_for_compose:
            builds.append((
                Path("/volume1/docker/nodedc-platform/platform/gelios-gateway"),
                ("build", "--no-cache", "-t", "nodedc/gelios-gateway:local", "."),
            ))
        if touches_map_gateway:
            builds.append((
                Path("/volume1/docker/nodedc-platform/platform/services/map-gateway"),
                ("build", "--no-cache", "-t", "nodedc/map-gateway:local", "."),
            ))
        if touches_external_data_plane:
            builds.append((
                Path("/volume1/docker/nodedc-platform/platform"),
                ("build", "--no-cache", "-f", "services/external-data-plane/Dockerfile", "-t", "nodedc/external-data-plane:local", "."),
            ))
        return tuple(builds)

    if component == "tasker":
        plane_src = Path("/volume1/docker/nodedc-platform/tasker/plane-src")
        return (
            (
                plane_src / "apps/api",
                (
                    "build",
                    "--network=host",
                    "-t",
                    "nodedc/plane-backend:local",
                    "-f",
                    "Dockerfile.api",
                    ".",
                ),
            ),
            (
                plane_src,
                (
                    "build",
                    "--network=host",
                    "--build-arg",
                    "VITE_NODEDC_LAUNCHER_URL=https://hub.nodedc.ru",
                    "--build-arg",
                    "VITE_NODEDC_OIDC_LOGIN_ENABLED=1",
                    "-t",
                    "nodedc/plane-frontend:ru",
                    "-f",
                    "apps/web/Dockerfile.web.nas-legacy",
                    ".",
                ),
            ),
        )

    build_root = component_build_root(component)
    build_args = component_build_args(component, entries)
    if build_root and build_args:
        return ((build_root, build_args),)
    return ()


def docker_json(args, label):
    result = subprocess.run(
        [str(DOCKER), *args],
        check=False,
        capture_output=True,
        text=True,
    )
    if result.returncode != 0:
        die(f"{label} failed: exit={result.returncode}")
    try:
        return json.loads(result.stdout)
    except json.JSONDecodeError:
        die(f"{label} returned invalid JSON")


def inspect_local_image(image_ref, label):
    images = docker_json(["image", "inspect", image_ref], f"{label} inspect")
    if not isinstance(images, list) or len(images) != 1 or not isinstance(images[0], dict):
        die(f"{label} inspect shape mismatch")
    image = images[0]
    image_id = image.get("Id")
    if (not isinstance(image_id, str)
            or not re.fullmatch(r"sha256:[a-f0-9]{64}", image_id)
            or image.get("Architecture") != "amd64"
            or image.get("Os") != "linux"):
        die(f"{label} identity/platform mismatch")
    return image_id


def inspect_optional_local_image(image_ref, label):
    result = subprocess.run(
        [str(DOCKER), "image", "inspect", image_ref],
        check=False,
        capture_output=True,
        text=True,
    )
    if result.returncode != 0:
        return None
    try:
        images = json.loads(result.stdout)
    except json.JSONDecodeError:
        die(f"{label} returned invalid JSON")
    if not isinstance(images, list) or len(images) != 1 or not isinstance(images[0], dict):
        die(f"{label} inspect shape mismatch")
    image = images[0]
    image_id = image.get("Id")
    if (not isinstance(image_id, str)
            or not re.fullmatch(r"sha256:[a-f0-9]{64}", image_id)
            or image.get("Architecture") != "amd64"
            or image.get("Os") != "linux"):
        die(f"{label} identity/platform mismatch")
    return image_id


def ensure_engine_node_intelligence_secret():
    try:
        runtime_stat = ENGINE_NODE_INTELLIGENCE_RUNTIME_DIR.lstat()
    except FileNotFoundError:
        ENGINE_NODE_INTELLIGENCE_RUNTIME_DIR.mkdir(parents=False, exist_ok=False)
        runtime_stat = ENGINE_NODE_INTELLIGENCE_RUNTIME_DIR.lstat()
    if stat.S_ISLNK(runtime_stat.st_mode) or not stat.S_ISDIR(runtime_stat.st_mode):
        die("Engine node-intelligence runtime directory is unsafe")
    os.chown(
        ENGINE_NODE_INTELLIGENCE_RUNTIME_DIR,
        0,
        ENGINE_NODE_INTELLIGENCE_RUNTIME_GID,
    )
    ENGINE_NODE_INTELLIGENCE_RUNTIME_DIR.chmod(0o710)

    try:
        secret_stat = ENGINE_NODE_INTELLIGENCE_SECRET_FILE.lstat()
    except FileNotFoundError:
        value = secrets.token_urlsafe(48)
        temporary = ENGINE_NODE_INTELLIGENCE_RUNTIME_DIR / (
            f".{ENGINE_NODE_INTELLIGENCE_SECRET_FILE.name}."
            f"{os.getpid()}.{time.time_ns()}.tmp"
        )
        descriptor = None
        try:
            descriptor = os.open(
                str(temporary),
                os.O_WRONLY | os.O_CREAT | os.O_EXCL,
                0o440,
            )
            os.write(descriptor, f"{value}\n".encode("ascii"))
            os.fsync(descriptor)
            os.fchown(descriptor, 0, ENGINE_NODE_INTELLIGENCE_RUNTIME_GID)
            os.fchmod(descriptor, 0o440)
            os.close(descriptor)
            descriptor = None
            os.replace(temporary, ENGINE_NODE_INTELLIGENCE_SECRET_FILE)
            fsync_directory(ENGINE_NODE_INTELLIGENCE_RUNTIME_DIR)
        finally:
            if descriptor is not None:
                os.close(descriptor)
            if temporary.exists():
                temporary.unlink()
        return "created"

    if (
        stat.S_ISLNK(secret_stat.st_mode)
        or not stat.S_ISREG(secret_stat.st_mode)
        or secret_stat.st_uid != 0
        or secret_stat.st_gid != ENGINE_NODE_INTELLIGENCE_RUNTIME_GID
        or stat.S_IMODE(secret_stat.st_mode) != 0o440
        or secret_stat.st_size < 49
        or secret_stat.st_size > 512
    ):
        die("Engine node-intelligence secret file is unsafe")
    try:
        value = ENGINE_NODE_INTELLIGENCE_SECRET_FILE.read_text(
            encoding="ascii"
        ).strip()
    except (OSError, UnicodeDecodeError):
        die("Engine node-intelligence secret file is unreadable")
    if not ENGINE_NODE_INTELLIGENCE_SECRET_RE.fullmatch(value):
        die("Engine node-intelligence secret file has invalid format")
    return "reused"


def inspect_engine_node_intelligence_image(descriptor, required=True):
    result = subprocess.run(
        [str(DOCKER), "image", "inspect", ENGINE_NODE_INTELLIGENCE_IMAGE],
        check=False,
        capture_output=True,
        text=True,
    )
    if result.returncode != 0:
        if not required:
            return None
        die("Engine node-intelligence image is missing")
    try:
        images = json.loads(result.stdout)
    except json.JSONDecodeError:
        die("Engine node-intelligence image inspect returned invalid JSON")
    if not isinstance(images, list) or len(images) != 1 or not isinstance(images[0], dict):
        die("Engine node-intelligence image inspect shape mismatch")
    image = images[0]
    image_id = image.get("Id")
    config = image.get("Config") or {}
    labels = config.get("Labels") or {}
    repo_tags = image.get("RepoTags") or []
    if (
        not isinstance(image_id, str)
        or not re.fullmatch(r"sha256:[a-f0-9]{64}", image_id)
        or image.get("Architecture") != descriptor["image"]["architecture"]
        or image.get("Os") != descriptor["image"]["os"]
        or ENGINE_NODE_INTELLIGENCE_IMAGE not in repo_tags
        or not isinstance(labels, dict)
        or labels.get("org.opencontainers.image.revision")
        != ENGINE_NODE_INTELLIGENCE_UPSTREAM_COMMIT
        or config.get("Entrypoint") != ["/usr/local/bin/docker-entrypoint.sh"]
        or config.get("Cmd") != ["node", "dist/mcp/index.js"]
    ):
        die("Engine node-intelligence image identity mismatch")
    env = config.get("Env") or []
    if any(
        str(value).startswith(("AUTH_TOKEN=", "N8N_API_URL=", "N8N_API_KEY="))
        for value in env
    ):
        die("Engine node-intelligence image contains runtime authority")
    return image


def install_engine_node_intelligence_image(descriptor):
    if descriptor.get("action") != "activate":
        die("Engine node-intelligence image install requires activation")
    source_archive = (
        component_root("engine") / ENGINE_NODE_INTELLIGENCE_IMAGE_ARCHIVE_REL
    )
    validate_engine_node_intelligence_image_archive(source_archive, descriptor)

    try:
        releases_stat = ENGINE_NODE_INTELLIGENCE_RELEASES_DIR.lstat()
    except FileNotFoundError:
        ENGINE_NODE_INTELLIGENCE_RELEASES_DIR.mkdir(parents=False, exist_ok=False)
        releases_stat = ENGINE_NODE_INTELLIGENCE_RELEASES_DIR.lstat()
    if stat.S_ISLNK(releases_stat.st_mode) or not stat.S_ISDIR(releases_stat.st_mode):
        die("Engine node-intelligence releases directory is unsafe")
    os.chown(ENGINE_NODE_INTELLIGENCE_RELEASES_DIR, 0, 0)
    ENGINE_NODE_INTELLIGENCE_RELEASES_DIR.chmod(0o500)

    release_dir = (
        ENGINE_NODE_INTELLIGENCE_RELEASES_DIR / descriptor["releaseId"]
    )
    try:
        release_stat = release_dir.lstat()
    except FileNotFoundError:
        ENGINE_NODE_INTELLIGENCE_RELEASES_DIR.chmod(0o700)
        try:
            release_dir.mkdir(mode=0o500, exist_ok=False)
        finally:
            ENGINE_NODE_INTELLIGENCE_RELEASES_DIR.chmod(0o500)
        release_stat = release_dir.lstat()
    if (
        stat.S_ISLNK(release_stat.st_mode)
        or not stat.S_ISDIR(release_stat.st_mode)
        or release_stat.st_uid != 0
    ):
        die("Engine node-intelligence release directory is unsafe")
    os.chown(release_dir, 0, 0)
    release_dir.chmod(0o500)

    release_archive = release_dir / "engine-node-intelligence.tar"
    if release_archive.exists() or release_archive.is_symlink():
        release_archive_stat = release_archive.lstat()
        if (
            stat.S_ISLNK(release_archive_stat.st_mode)
            or not stat.S_ISREG(release_archive_stat.st_mode)
            or release_archive_stat.st_uid != 0
            or release_archive_stat.st_gid != 0
            or stat.S_IMODE(release_archive_stat.st_mode) != 0o400
            or sha256_file(release_archive) != descriptor["image"]["archiveSha256"]
        ):
            die("Engine node-intelligence sealed release collision")
    else:
        release_dir.chmod(0o700)
        temporary = release_dir / (
            f".engine-node-intelligence.tar.{os.getpid()}.{time.time_ns()}.tmp"
        )
        try:
            with source_archive.open("rb") as source, temporary.open("xb") as output:
                shutil.copyfileobj(source, output, 1024 * 1024)
                output.flush()
                os.fsync(output.fileno())
            os.chown(temporary, 0, 0)
            temporary.chmod(0o400)
            if sha256_file(temporary) != descriptor["image"]["archiveSha256"]:
                die("Engine node-intelligence sealed release copy mismatch")
            os.replace(temporary, release_archive)
            fsync_directory(release_dir)
        finally:
            if temporary.exists():
                temporary.unlink()
            release_dir.chmod(0o500)

    load = subprocess.run(
        [str(DOCKER), "image", "load", "--input", str(release_archive)],
        check=False,
        capture_output=True,
        text=True,
        timeout=600,
    )
    if load.returncode != 0:
        die("Engine node-intelligence offline image load failed")
    image = inspect_engine_node_intelligence_image(descriptor)
    return image["Id"]


def engine_backend_container_id():
    result = subprocess.run(
        [*compose_base_cmd("engine"), "ps", "-q", "nodedc-backend"],
        cwd=str(component_compose_root("engine")),
        check=False,
        capture_output=True,
        text=True,
    )
    container_ids = [line.strip() for line in result.stdout.splitlines() if line.strip()]
    if (result.returncode != 0
            or len(container_ids) != 1
            or not re.fullmatch(r"[a-f0-9]{12,64}", container_ids[0])):
        die("Engine backend topology mismatch")
    return container_ids[0]


def engine_backend_container_id_for_gateway(expected_gateway_sha256):
    return engine_compose_service_container_id_for_gateway(
        "nodedc-backend",
        expected_gateway_sha256,
    )


def engine_compose_service_container_id_for_gateway(
    service,
    expected_gateway_sha256,
):
    if service not in ("nodedc-backend", "app"):
        die("Engine L2 closed-loop service lookup is not registered")
    result = subprocess.run(
        [
            *compose_base_cmd(
                "engine",
                expected_node_intelligence_gateway_sha256=
                    expected_gateway_sha256,
            ),
            "ps",
            "-q",
            service,
        ],
        cwd=str(component_compose_root("engine")),
        check=False,
        capture_output=True,
        text=True,
    )
    container_ids = [line.strip() for line in result.stdout.splitlines() if line.strip()]
    if (result.returncode != 0
            or len(container_ids) != 1
            or not re.fullmatch(r"[a-f0-9]{12,64}", container_ids[0])):
        die(f"Engine L2 closed-loop service topology mismatch: {service}")
    return container_ids[0]


def run_engine_backend_probe(arguments, label, container_id=None, image_ref=None):
    if (container_id is None) == (image_ref is None):
        die(f"{label} probe target mismatch")
    if container_id is not None:
        cmd = [str(DOCKER), "exec", container_id, *arguments]
    else:
        cmd = [
            str(DOCKER), "run", "--rm", "--network", "none",
            "--tmpfs", "/tmp:mode=1777", "--env", "HOME=/tmp",
            image_ref, *arguments,
        ]
    result = subprocess.run(
        cmd,
        check=False,
        capture_output=True,
        text=True,
        timeout=90,
    )
    value = result.stdout.strip()
    if (result.returncode != 0
            or result.stderr.strip()
            or not value
            or len(value) > 512
            or any(ord(character) < 0x20 and character not in "\t" for character in value)):
        die(f"Engine backend {label} probe failed")
    return value


def engine_backend_tool_versions(container_id=None, image_ref=None):
    versions = {
        "node": run_engine_backend_probe(("node", "--version"), "node", container_id, image_ref),
        "sqlite": run_engine_backend_probe(("sqlite3", "--version"), "sqlite", container_id, image_ref),
        "docker": run_engine_backend_probe(("docker", "--version"), "docker", container_id, image_ref),
        "compose": run_engine_backend_probe(
            ("docker", "compose", "version"), "Docker Compose", container_id, image_ref
        ),
    }
    if (not re.fullmatch(r"v20\.[0-9]+\.[0-9]+", versions["node"])
            or not re.fullmatch(r"[0-9]+\.[0-9]+\.[0-9]+(?:\s+.*)?", versions["sqlite"])
            or not re.fullmatch(r"Docker version [0-9]+\.[0-9]+\.[0-9]+, build [A-Za-z0-9._-]+", versions["docker"])
            or not re.fullmatch(r"Docker Compose version v?[0-9]+\.[0-9]+\.[0-9]+(?:[-+][A-Za-z0-9._-]+)?", versions["compose"])):
        die("Engine backend runtime tool version format mismatch")
    return versions


def validate_engine_backend_mounts(container, node_modules_read_only):
    expected = {
        "/app": ("bind", True),
        "/app/deploy/docker-compose.yml": ("bind", False),
        "/seed-api": ("bind", False),
        "/seed-data": ("bind", False),
        "/app/node_modules": ("bind", not node_modules_read_only),
        "/app/server/data": ("bind", True),
        "/app/server/storage": ("bind", True),
        "/app/server/logs": ("bind", True),
        "/var/run/docker.sock": ("bind", True),
    }
    mounts = container.get("Mounts")
    if not isinstance(mounts, list):
        die("Engine backend mount inventory is missing")
    actual = {}
    node_modules_source = None
    for mount in mounts:
        if not isinstance(mount, dict) or not isinstance(mount.get("Destination"), str):
            die("Engine backend mount inventory is invalid")
        destination = mount["Destination"]
        if destination in actual:
            die(f"Engine backend duplicate mount destination: {destination}")
        actual[destination] = (mount.get("Type"), bool(mount.get("RW")))
        if destination == "/app/node_modules":
            node_modules_source = mount.get("Source")
    if actual != expected:
        die("Engine backend mount barrier mismatch")
    if (node_modules_source != str(ENGINE_CREDENTIAL_BACKEND_NODE_MODULES_DIR)
            or not ENGINE_CREDENTIAL_BACKEND_NODE_MODULES_DIR.is_absolute()):
        die("Engine backend node_modules mount source mismatch")


def validate_engine_backend_mounts_for_installed_runtime(
    container,
    node_modules_read_only,
):
    publish_override = (
        component_root("engine")
        / ENGINE_DATA_PRODUCT_PUBLISH_GRANT_OVERRIDE_REL
    )
    publish_installed = publish_override.exists() or publish_override.is_symlink()
    if not publish_installed:
        # The legacy credential runtime remains byte-for-byte authoritative
        # until the exact Publish overlay has been installed.
        return validate_engine_backend_mounts(container, node_modules_read_only)

    if publish_override.is_symlink() or not publish_override.is_file():
        die("installed Engine data product publish grant override is unsafe")
    try:
        publish_override_text = publish_override.read_text(encoding="utf-8")
    except (OSError, UnicodeDecodeError):
        die("installed Engine data product publish grant override cannot be read")
    if publish_override_text != expected_engine_data_product_publish_grant_override():
        die("installed Engine data product publish grant override drift detected")

    expected_publish_mounts = {
        ENGINE_PUBLISH_GRANT_CONTAINER_PATH: (
            "bind",
            True,
            str(ENGINE_PUBLISH_GRANT_STATE_PATH),
        ),
        ENGINE_EDP_PRIVATE_KEY_CONTAINER_PATH: (
            "bind",
            False,
            str(ENGINE_EDP_MANAGED_PROVISIONER_PRIVATE_KEY_FILE),
        ),
    }
    read_override = component_root("engine") / ENGINE_DATA_PRODUCT_READ_GRANT_OVERRIDE_REL
    read_installed = read_override.exists() or read_override.is_symlink()
    if read_installed:
        if read_override.is_symlink() or not read_override.is_file():
            die("installed Engine data product read grant override is unsafe")
        try:
            read_override_text = read_override.read_text(encoding="utf-8")
        except (OSError, UnicodeDecodeError):
            die("installed Engine data product read grant override cannot be read")
        if read_override_text != expected_engine_data_product_read_grant_override():
            die("installed Engine data product read grant override drift detected")
        expected_publish_mounts[ENGINE_READ_GRANT_CONTAINER_PATH] = (
            "bind",
            True,
            str(ENGINE_READ_GRANT_STATE_PATH),
        )
    mounts = container.get("Mounts")
    if not isinstance(mounts, list):
        die("Engine backend mount inventory is missing")
    baseline_mounts = []
    observed_publish_mounts = set()
    for mount in mounts:
        if not isinstance(mount, dict) or not isinstance(mount.get("Destination"), str):
            die("Engine backend mount inventory is invalid")
        destination = mount["Destination"]
        expected = expected_publish_mounts.get(destination)
        if expected is None:
            baseline_mounts.append(mount)
            continue
        if destination in observed_publish_mounts:
            die(f"Engine backend duplicate mount destination: {destination}")
        actual = (
            mount.get("Type"),
            bool(mount.get("RW")),
            mount.get("Source"),
        )
        if actual != expected:
            die(f"Engine backend Publish mount barrier mismatch: {destination}")
        observed_publish_mounts.add(destination)
    if observed_publish_mounts != set(expected_publish_mounts):
        die("Engine backend Publish mount inventory mismatch")

    projected = dict(container)
    projected["Mounts"] = baseline_mounts
    return validate_engine_backend_mounts(projected, node_modules_read_only)


def validate_engine_backend_node_intelligence_mounts_for_installed_runtime(
    container,
    node_modules_read_only,
    expected_gateway_sha256=None,
):
    descriptor = current_engine_node_intelligence_descriptor()
    active = descriptor is not None and descriptor["action"] == "activate"
    if not active:
        # The pre-existing runtime guard remains authoritative when this
        # independent overlay is inactive. Any stray secret mount therefore
        # still fails its exact baseline inventory.
        return validate_engine_backend_mounts_for_installed_runtime(
            container,
            node_modules_read_only,
        )

    if expected_gateway_sha256 is None:
        validate_installed_engine_node_intelligence_source(descriptor)
    else:
        validate_installed_engine_node_intelligence_source(
            descriptor,
            expected_gateway_sha256=expected_gateway_sha256,
        )
    mounts = container.get("Mounts")
    if not isinstance(mounts, list):
        die("Engine backend mount inventory is missing")
    baseline_mounts = []
    observed = 0
    for mount in mounts:
        if not isinstance(mount, dict) or not isinstance(mount.get("Destination"), str):
            die("Engine backend mount inventory is invalid")
        if mount["Destination"] != ENGINE_NODE_INTELLIGENCE_SECRET_CONTAINER_PATH:
            baseline_mounts.append(mount)
            continue
        observed += 1
        actual = (
            mount.get("Type"),
            bool(mount.get("RW")),
            mount.get("Source"),
        )
        expected = (
            "bind",
            False,
            str(ENGINE_NODE_INTELLIGENCE_SECRET_FILE),
        )
        if observed != 1 or actual != expected:
            die("Engine backend node-intelligence mount barrier mismatch")
    if observed != 1:
        die("Engine backend node-intelligence mount inventory mismatch")

    # Remove only the independently proven additive mount, then delegate the
    # remaining inventory to the existing Publish-aware guard and ultimately
    # the byte-protected legacy baseline validator.
    projected = dict(container)
    projected["Mounts"] = baseline_mounts
    return validate_engine_backend_mounts_for_installed_runtime(
        projected,
        node_modules_read_only,
    )


def validate_engine_backend_dependencies(container_id):
    package_path = component_root("engine") / "nodedc-source/package.json"
    try:
        package_stat = package_path.lstat()
    except FileNotFoundError:
        die("Engine backend package.json is missing")
    if stat.S_ISLNK(package_stat.st_mode) or not stat.S_ISREG(package_stat.st_mode):
        die("Engine backend package.json is unsafe")
    package = read_strict_json(package_path, "Engine backend package.json", max_bytes=2 * 1024 * 1024)
    dependencies = package.get("dependencies")
    if not isinstance(dependencies, dict) or not dependencies:
        die("Engine backend dependency manifest is invalid")
    names = sorted(dependencies)
    if any(not re.fullmatch(r"(?:@[a-z0-9._-]+/)?[a-z0-9._-]+", name) for name in names):
        die("Engine backend dependency name is unsafe")
    script = (
        "const names=" + json.dumps(names, separators=(",", ":"))
        + ";for(const name of names)require.resolve(name,{paths:['/app']});"
        + "process.stdout.write('dependencies-ok')"
    )
    result = subprocess.run(
        [str(DOCKER), "exec", "--workdir", "/app", container_id, "node", "-e", script],
        check=False,
        capture_output=True,
        text=True,
        timeout=120,
    )
    if result.returncode != 0 or result.stderr.strip() or result.stdout.strip() != "dependencies-ok":
        die("Engine backend mounted dependency barrier mismatch")


def engine_backend_node_modules_tree_sha256(container_id):
    script = """
const crypto=require('crypto');
const fs=require('fs');
const path=require('path');
const root='/app/node_modules';
const hash=crypto.createHash('sha256');
const lock=JSON.parse(fs.readFileSync('/app/package-lock.json','utf8'));
if(lock.lockfileVersion!==3||!lock.packages||typeof lock.packages!=='object')throw new Error('lock-invalid');
const expected=new Map(Object.entries(lock.packages).filter(([key,value])=>key.startsWith('node_modules/')&&value&&typeof value==='object'));
function secure(stat,label,{symlink=false}={}){
  if(stat.uid!==0||stat.gid!==0)throw new Error('owner:'+label);
  if(!symlink&&(stat.mode&0o022)!==0)throw new Error('writable:'+label);
}
secure(fs.lstatSync(root),'root');
function packageVersion(packageRoot,key){
  const manifest=JSON.parse(fs.readFileSync(path.join(packageRoot,'package.json'),'utf8'));
  const wanted=expected.get(key);
  if(!wanted||String(manifest.version||'')!==String(wanted.version||''))throw new Error('package-version:'+key);
}
function inspectPackageDirectory(nodeModulesRoot,relativePrefix){
  const names=fs.readdirSync(nodeModulesRoot).sort((a,b)=>Buffer.from(a).compare(Buffer.from(b)));
  const roots=[];
  for(const name of names){
    if(name==='.bin'||name==='.package-lock.json')continue;
    const candidate=path.join(nodeModulesRoot,name);
    const stat=fs.lstatSync(candidate);
    if(name.startsWith('@')){
      if(!stat.isDirectory())throw new Error('scope-not-directory');
      for(const child of fs.readdirSync(candidate).sort((a,b)=>Buffer.from(a).compare(Buffer.from(b)))){
        roots.push([path.join(candidate,child),relativePrefix+name+'/'+child]);
      }
    }else{
      roots.push([candidate,relativePrefix+name]);
    }
  }
  for(const [packageRoot,key] of roots){
    const stat=fs.lstatSync(packageRoot);
    if(!stat.isDirectory()||stat.isSymbolicLink())throw new Error('package-boundary:'+key);
    packageVersion(packageRoot,key);
    const nested=path.join(packageRoot,'node_modules');
    if(fs.existsSync(nested))inspectPackageDirectory(nested,key+'/node_modules/');
  }
}
inspectPackageDirectory(root,'node_modules/');
for(const [key,value] of expected){
  const target=path.join('/app',key);
  if(!fs.existsSync(target)&&value.optional!==true)throw new Error('package-missing:'+key);
  if(fs.existsSync(target))packageVersion(target,key);
}
function visit(relative){
  const absolute=path.join(root,relative);
  const names=fs.readdirSync(absolute).sort((a,b)=>Buffer.from(a).compare(Buffer.from(b)));
  for(const name of names){
    if(name.includes('\\0')||name==='.'||name==='..')throw new Error('unsafe-name');
    const child=relative?relative+'/'+name:name;
    const target=path.join(root,child);
    const stat=fs.lstatSync(target);
    const mode=(stat.mode&0o7777).toString(8);
    if(stat.isDirectory()){
      secure(stat,child);
      hash.update('d\\0'+child+'\\0'+mode+'\\0');
      visit(child);
    }else if(stat.isFile()){
      secure(stat,child);
      hash.update('f\\0'+child+'\\0'+mode+'\\0'+stat.size+'\\0');
      hash.update(fs.readFileSync(target));
    }else if(stat.isSymbolicLink()){
      secure(stat,child,{symlink:true});
      const link=fs.readlinkSync(target);
      if(path.isAbsolute(link))throw new Error('absolute-link:'+child);
      const resolved=path.resolve(path.dirname(target),link);
      if(resolved!==root&&!resolved.startsWith(root+'/'))throw new Error('escaping-link:'+child);
      const real=fs.realpathSync(target);
      if(real!==root&&!real.startsWith(root+'/'))throw new Error('escaping-real-link:'+child);
      hash.update('l\\0'+child+'\\0'+mode+'\\0'+link+'\\0');
    }else{
      throw new Error('special-file');
    }
  }
}
visit('');
process.stdout.write('sha256:'+hash.digest('hex'));
""".strip()
    result = subprocess.run(
        [str(DOCKER), "exec", "--workdir", "/app", container_id, "node", "-e", script],
        check=False,
        capture_output=True,
        text=True,
        timeout=300,
    )
    value = result.stdout.strip()
    if (result.returncode != 0
            or result.stderr.strip()
            or not re.fullmatch(r"sha256:[a-f0-9]{64}", value)):
        die("Engine backend node_modules tree proof failed")
    return value


def validate_runtime_owned_file(path, mode, label, min_bytes=1, max_bytes=1024 * 1024 * 1024):
    try:
        path_stat = path.lstat()
    except FileNotFoundError:
        die(f"{label} is missing")
    if (stat.S_ISLNK(path_stat.st_mode)
            or not stat.S_ISREG(path_stat.st_mode)
            or path_stat.st_uid != 0
            or path_stat.st_gid != 0
            or stat.S_IMODE(path_stat.st_mode) != mode
            or path_stat.st_size < min_bytes
            or path_stat.st_size > max_bytes):
        die(f"{label} is unsafe")
    return path_stat


def validate_engine_backend_runtime_override_file():
    validate_runtime_owned_file(
        ENGINE_CREDENTIAL_BACKEND_OVERRIDE_FILE,
        0o600,
        "Engine backend immutable runtime override",
        max_bytes=64 * 1024,
    )
    try:
        value = ENGINE_CREDENTIAL_BACKEND_OVERRIDE_FILE.read_text(encoding="utf-8")
    except (OSError, UnicodeDecodeError):
        die("Engine backend immutable runtime override is unreadable")
    if value != expected_engine_credential_backend_override():
        die("Engine backend immutable runtime override drift detected")
    return sha256_file(ENGINE_CREDENTIAL_BACKEND_OVERRIDE_FILE)


def validate_engine_backend_activation_marker():
    validate_runtime_owned_file(
        ENGINE_CREDENTIAL_BACKEND_ACTIVATION_FILE,
        0o600,
        "Engine backend immutable runtime activation marker",
        max_bytes=128,
    )
    validate_engine_backend_runtime_override_file()
    metadata = read_engine_backend_runtime_metadata()
    validate_runtime_owned_file(
        ENGINE_CREDENTIAL_BACKEND_ROOTFS_FILE,
        0o600,
        "Engine backend canonical rootfs",
        max_bytes=MAX_PAYLOAD_BYTES,
    )
    expected = f"sha256:{sha256_file(ENGINE_CREDENTIAL_BACKEND_METADATA_FILE)}\n"
    try:
        actual = ENGINE_CREDENTIAL_BACKEND_ACTIVATION_FILE.read_text(encoding="ascii")
    except (OSError, UnicodeDecodeError):
        die("Engine backend immutable runtime activation marker is unreadable")
    if (actual != expected
            or sha256_file(ENGINE_CREDENTIAL_BACKEND_ROOTFS_FILE) != metadata["rootfsSha256"]):
        die("Engine backend immutable runtime activation marker mismatch")
    inspect_engine_backend_derived_image(metadata)
    return metadata


def quarantine_engine_backend_partial_runtime():
    runtime_exists = (
        ENGINE_CREDENTIAL_BACKEND_RUNTIME_DIR.exists()
        or ENGINE_CREDENTIAL_BACKEND_RUNTIME_DIR.is_symlink()
    )
    if not runtime_exists:
        return "absent"
    ensure_root_runtime_directory(ENGINE_CREDENTIAL_BACKEND_RUNTIME_DIR)
    present = [
        path for path in (
            ENGINE_CREDENTIAL_BACKEND_ACTIVATION_FILE,
            ENGINE_CREDENTIAL_BACKEND_OVERRIDE_FILE,
            ENGINE_CREDENTIAL_BACKEND_METADATA_FILE,
            ENGINE_CREDENTIAL_BACKEND_ROOTFS_FILE,
        )
        if path.exists() or path.is_symlink()
    ]
    if not present:
        return "empty"
    failed_root = ENGINE_CREDENTIAL_BACKEND_RUNTIME_DIR / "failed"
    ensure_root_runtime_directory(failed_root)
    quarantine = failed_root / f"{stamp()}-{os.getpid()}-{time.time_ns()}"
    quarantine.mkdir(mode=0o700)
    os.chown(quarantine, 0, 0)
    # Move the activation marker first. Once this succeeds, no subsequent
    # Engine Compose command can consume the incomplete override.
    ordered = sorted(
        present,
        key=lambda path: path != ENGINE_CREDENTIAL_BACKEND_ACTIVATION_FILE,
    )
    for path in ordered:
        os.replace(path, quarantine / path.name)
        fsync_directory(ENGINE_CREDENTIAL_BACKEND_RUNTIME_DIR)
    fsync_directory(quarantine)
    return "quarantined"


def read_engine_backend_runtime_metadata():
    validate_runtime_owned_file(
        ENGINE_CREDENTIAL_BACKEND_METADATA_FILE,
        0o600,
        "Engine backend immutable runtime metadata",
        max_bytes=64 * 1024,
    )
    value = read_strict_json(
        ENGINE_CREDENTIAL_BACKEND_METADATA_FILE,
        "Engine backend immutable runtime metadata",
        max_bytes=64 * 1024,
    )
    expected_keys = {
        "schemaVersion", "release", "sourceContainerId", "sourceImageId",
        "derivedImageId", "rootfsSha256", "packageLockSha256",
        "nodeModulesTreeSha256", "overrideSha256", "tools",
    }
    if (not isinstance(value, dict)
            or set(value) != expected_keys
            or value.get("schemaVersion") != "nodedc.engine-backend-immutable-runtime/v1"
            or value.get("release") != "credential-sink-20260716-001"
            or not re.fullmatch(r"[a-f0-9]{12,64}", str(value.get("sourceContainerId")))
            or not re.fullmatch(r"sha256:[a-f0-9]{64}", str(value.get("sourceImageId")))
            or not re.fullmatch(r"sha256:[a-f0-9]{64}", str(value.get("derivedImageId")))
            or not re.fullmatch(r"[a-f0-9]{64}", str(value.get("rootfsSha256")))
            or value.get("packageLockSha256") != ENGINE_CREDENTIAL_BACKEND_PACKAGE_LOCK_SHA256
            or not re.fullmatch(r"sha256:[a-f0-9]{64}", str(value.get("nodeModulesTreeSha256")))
            or not re.fullmatch(r"[a-f0-9]{64}", str(value.get("overrideSha256")))
            or not isinstance(value.get("tools"), dict)
            or set(value["tools"]) != {"node", "sqlite", "docker", "compose"}):
        die("Engine backend immutable runtime metadata mismatch")
    return value


def inspect_engine_backend_derived_image(
    expected_metadata=None,
    image_ref=ENGINE_CREDENTIAL_BACKEND_IMAGE,
    expected_source_image_id=None,
    expected_rootfs_sha256=None,
):
    images = docker_json(
        ["image", "inspect", image_ref],
        "Engine backend immutable image inspect",
    )
    if not isinstance(images, list) or len(images) != 1 or not isinstance(images[0], dict):
        die("Engine backend immutable image inspect shape mismatch")
    image = images[0]
    image_id = image.get("Id")
    labels = (image.get("Config") or {}).get("Labels") or {}
    if (not isinstance(image_id, str)
            or not re.fullmatch(r"sha256:[a-f0-9]{64}", image_id)
            or image.get("Architecture") != "amd64"
            or image.get("Os") != "linux"
            or not isinstance(labels, dict)
            or labels.get("org.nodedc.release") != "credential-sink-20260716-001"
            or labels.get("org.nodedc.package-lock-sha256") != ENGINE_CREDENTIAL_BACKEND_PACKAGE_LOCK_SHA256
            or not re.fullmatch(r"sha256:[a-f0-9]{64}", str(labels.get("org.nodedc.source-image-id")))
            or not re.fullmatch(r"[a-f0-9]{64}", str(labels.get("org.nodedc.rootfs-sha256")))):
        die("Engine backend immutable image identity mismatch")
    if (expected_source_image_id is not None
            and labels["org.nodedc.source-image-id"] != expected_source_image_id):
        die("Engine backend immutable image source collision")
    if (expected_rootfs_sha256 is not None
            and labels["org.nodedc.rootfs-sha256"] != expected_rootfs_sha256):
        die("Engine backend immutable image rootfs collision")
    if expected_metadata is not None and (
        image_id != expected_metadata["derivedImageId"]
        or labels["org.nodedc.source-image-id"] != expected_metadata["sourceImageId"]
        or labels["org.nodedc.rootfs-sha256"] != expected_metadata["rootfsSha256"]
    ):
        die("Engine backend immutable image metadata drift detected")
    return image


def ensure_engine_backend_release_image(
    build_context,
    source_image_id,
    rootfs_sha256,
    expected_tools,
):
    target_id = inspect_optional_local_image(
        ENGINE_CREDENTIAL_BACKEND_IMAGE,
        "Engine backend immutable release image",
    )
    if target_id is not None:
        image = inspect_engine_backend_derived_image(
            image_ref=ENGINE_CREDENTIAL_BACKEND_IMAGE,
            expected_source_image_id=source_image_id,
            expected_rootfs_sha256=rootfs_sha256,
        )
        if (image.get("Id") != target_id
                or engine_backend_tool_versions(
                    image_ref=ENGINE_CREDENTIAL_BACKEND_IMAGE,
                ) != expected_tools):
            die("Engine backend immutable release image collision")
        return image

    build_ref = f"nodedc/deploy-build:engine-backend-{rootfs_sha256[:16]}"
    build_id = inspect_optional_local_image(
        build_ref,
        "Engine backend immutable build image",
    )
    if build_id is None:
        build = subprocess.run(
            [
                str(DOCKER), "build", "--no-cache", "--network", "none", "--pull=false",
                "-f", "Dockerfile", "-t", build_ref, ".",
            ],
            cwd=str(build_context),
            check=False,
            timeout=600,
        )
        if build.returncode != 0:
            die("Engine backend immutable image build failed")
        build_id = inspect_optional_local_image(
            build_ref,
            "Engine backend immutable built image",
        )
        if build_id is None:
            die("Engine backend immutable built image is missing")

    build_image = inspect_engine_backend_derived_image(
        image_ref=build_ref,
        expected_source_image_id=source_image_id,
        expected_rootfs_sha256=rootfs_sha256,
    )
    if (build_image.get("Id") != build_id
            or engine_backend_tool_versions(image_ref=build_ref) != expected_tools):
        die("Engine backend immutable build image collision")

    # The deploy lock serializes canonical applies. Recheck the release tag
    # immediately before assigning it so an existing versioned identity is
    # never intentionally moved to a different image.
    target_id = inspect_optional_local_image(
        ENGINE_CREDENTIAL_BACKEND_IMAGE,
        "Engine backend immutable release image recheck",
    )
    if target_id is not None:
        image = inspect_engine_backend_derived_image(
            image_ref=ENGINE_CREDENTIAL_BACKEND_IMAGE,
            expected_source_image_id=source_image_id,
            expected_rootfs_sha256=rootfs_sha256,
        )
        if image.get("Id") != build_id:
            die("Engine backend immutable release image collision")
        return image
    tag = subprocess.run(
        [str(DOCKER), "image", "tag", build_id, ENGINE_CREDENTIAL_BACKEND_IMAGE],
        check=False,
        stdout=subprocess.DEVNULL,
        stderr=subprocess.DEVNULL,
    )
    if tag.returncode != 0:
        die("Engine backend immutable release image tag failed")
    image = inspect_engine_backend_derived_image(
        image_ref=ENGINE_CREDENTIAL_BACKEND_IMAGE,
        expected_source_image_id=source_image_id,
        expected_rootfs_sha256=rootfs_sha256,
    )
    if (image.get("Id") != build_id
            or engine_backend_tool_versions(
                image_ref=ENGINE_CREDENTIAL_BACKEND_IMAGE,
            ) != expected_tools):
        die("Engine backend immutable release image verification failed")
    return image


def preflight_engine_credential_backend_runtime(
    expected_node_intelligence_gateway_sha256=None,
):
    base_image_id = inspect_local_image(
        ENGINE_CREDENTIAL_BACKEND_BASE_IMAGE,
        "Engine backend base image",
    )
    package_lock = component_root("engine") / "nodedc-source/package-lock.json"
    try:
        lock_stat = package_lock.lstat()
    except FileNotFoundError:
        die("Engine backend package-lock.json is missing")
    if (stat.S_ISLNK(lock_stat.st_mode)
            or not stat.S_ISREG(lock_stat.st_mode)
            or sha256_file(package_lock) != ENGINE_CREDENTIAL_BACKEND_PACKAGE_LOCK_SHA256):
        die("Engine backend package-lock barrier mismatch")
    try:
        node_modules_stat = ENGINE_CREDENTIAL_BACKEND_NODE_MODULES_DIR.lstat()
    except FileNotFoundError:
        die("Engine backend node_modules host source is missing")
    if (stat.S_ISLNK(node_modules_stat.st_mode)
            or not stat.S_ISDIR(node_modules_stat.st_mode)
            or node_modules_stat.st_uid != 0
            or node_modules_stat.st_gid != 0
            or node_modules_stat.st_mode & (stat.S_IWGRP | stat.S_IWOTH)):
        die("Engine backend node_modules host source is unsafe")

    container_id = (
        engine_backend_container_id()
        if expected_node_intelligence_gateway_sha256 is None
        else engine_backend_container_id_for_gateway(
            expected_node_intelligence_gateway_sha256
        )
    )
    containers = docker_json(["container", "inspect", container_id], "Engine backend container inspect")
    if not isinstance(containers, list) or len(containers) != 1 or not isinstance(containers[0], dict):
        die("Engine backend container inspect shape mismatch")
    container = containers[0]
    state = container.get("State") or {}
    started_at = state.get("StartedAt")
    initial_restart_count = int(container.get("RestartCount") or 0)
    if (state.get("Status") != "running"
            or (state.get("Health") or {}).get("Status") != "healthy"
            or not isinstance(started_at, str)
            or not re.fullmatch(r"[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9:.]+Z", started_at)):
        die("Engine backend source container is not stable and healthy")
    config_image = (container.get("Config") or {}).get("Image")
    current_image_id = container.get("Image")
    validate_engine_backend_node_intelligence_mounts_for_installed_runtime(
        container,
        node_modules_read_only=config_image == ENGINE_CREDENTIAL_BACKEND_IMAGE,
        expected_gateway_sha256=expected_node_intelligence_gateway_sha256,
    )
    if config_image == ENGINE_CREDENTIAL_BACKEND_BASE_IMAGE and current_image_id == base_image_id:
        runtime_presence = {
            "activation": ENGINE_CREDENTIAL_BACKEND_ACTIVATION_FILE.exists()
                or ENGINE_CREDENTIAL_BACKEND_ACTIVATION_FILE.is_symlink(),
            "override": ENGINE_CREDENTIAL_BACKEND_OVERRIDE_FILE.exists()
                or ENGINE_CREDENTIAL_BACKEND_OVERRIDE_FILE.is_symlink(),
            "metadata": ENGINE_CREDENTIAL_BACKEND_METADATA_FILE.exists()
                or ENGINE_CREDENTIAL_BACKEND_METADATA_FILE.is_symlink(),
            "rootfs": ENGINE_CREDENTIAL_BACKEND_ROOTFS_FILE.exists()
                or ENGINE_CREDENTIAL_BACKEND_ROOTFS_FILE.is_symlink(),
        }
        if all(runtime_presence.values()):
            validate_engine_backend_activation_marker()
            override_sha256 = validate_engine_backend_runtime_override_file()
            metadata = read_engine_backend_runtime_metadata()
            rootfs_stat = validate_runtime_owned_file(
                ENGINE_CREDENTIAL_BACKEND_ROOTFS_FILE,
                0o600,
                "Engine backend canonical rootfs",
                max_bytes=MAX_PAYLOAD_BYTES,
            )
            image = inspect_engine_backend_derived_image(metadata)
            if (rootfs_stat.st_size <= 0
                    or sha256_file(ENGINE_CREDENTIAL_BACKEND_ROOTFS_FILE) != metadata["rootfsSha256"]
                    or override_sha256 != metadata["overrideSha256"]
                    or metadata["sourceImageId"] != base_image_id
                    or metadata["derivedImageId"] != image.get("Id")):
                die("Engine backend prepared immutable runtime drift detected")
            mode = "verified-prepared-not-active"
        elif any(runtime_presence.values()):
            for name, path in (
                ("activation", ENGINE_CREDENTIAL_BACKEND_ACTIVATION_FILE),
                ("override", ENGINE_CREDENTIAL_BACKEND_OVERRIDE_FILE),
                ("metadata", ENGINE_CREDENTIAL_BACKEND_METADATA_FILE),
                ("rootfs", ENGINE_CREDENTIAL_BACKEND_ROOTFS_FILE),
            ):
                if runtime_presence[name]:
                    validate_runtime_owned_file(
                        path,
                        0o600,
                        f"Engine backend partial runtime {name}",
                        max_bytes=MAX_PAYLOAD_BYTES,
                    )
            mode = "recoverable-prepared-partial"
        else:
            mode = "verified-running-base"
        source_image_id = base_image_id
    elif config_image == ENGINE_CREDENTIAL_BACKEND_IMAGE:
        override_sha256 = validate_engine_backend_runtime_override_file()
        metadata = read_engine_backend_runtime_metadata()
        image = inspect_engine_backend_derived_image(metadata)
        if current_image_id != image.get("Id") or override_sha256 != metadata["overrideSha256"]:
            die("Engine backend immutable runtime activation drift detected")
        mode = "verified-derived-retry"
        source_image_id = metadata["sourceImageId"]
    else:
        die("Engine backend current image barrier mismatch")
    tools = engine_backend_tool_versions(container_id=container_id)
    validate_engine_backend_dependencies(container_id)
    node_modules_tree_sha256 = engine_backend_node_modules_tree_sha256(container_id)
    if mode in ("verified-derived-retry", "verified-prepared-not-active"):
        if (node_modules_tree_sha256 != metadata["nodeModulesTreeSha256"]
                or tools != metadata["tools"]):
            die("Engine backend prepared runtime source proof drift detected")
    stable = docker_json(["container", "inspect", container_id], "Engine backend stability inspect")
    stable_container = stable[0] if isinstance(stable, list) and len(stable) == 1 else None
    stable_state = stable_container.get("State") if isinstance(stable_container, dict) else None
    if (not isinstance(stable_state, dict)
            or stable_state.get("Status") != "running"
            or (stable_state.get("Health") or {}).get("Status") != "healthy"
            or stable_state.get("StartedAt") != started_at
            or int(stable_container.get("RestartCount") or 0) != initial_restart_count):
        die("Engine backend restarted during immutable runtime preflight")
    return {
        "base_image_id": base_image_id,
        "container_id": container_id,
        "current_image_id": current_image_id,
        "mode": mode,
        "source_image_id": source_image_id,
        "node_modules_tree_sha256": node_modules_tree_sha256,
        "tools": tools,
    }


def normalize_rootfs_member_name(name):
    if not isinstance(name, str) or not name or name.startswith("/") or "\\" in name:
        die("Engine backend export member path is unsafe")
    while name.startswith("./"):
        name = name[2:]
    parts = name.split("/")
    if not name or any(not part or part in (".", "..") for part in parts):
        die("Engine backend export member path is unsafe")
    if any(part.startswith("._") or part == "__MACOSX" for part in parts):
        die("Engine backend export contains AppleDouble metadata")
    return "/".join(parts)


def engine_backend_rootfs_member_allowed(name, is_directory):
    excluded = (
        "etc/hosts", "etc/hostname", "etc/resolv.conf", "etc/mtab",
        "etc/environment", "etc/profile", "etc/profile.d", "etc/ssl/private",
        "etc/ssh/ssh_host", "etc/machine-id", "etc/docker", "etc/containerd",
        "usr/local/etc", "usr/local/lib/node_modules",
    )
    if any(name == value or name.startswith(f"{value}/") for value in excluded):
        return False
    basename = name.rsplit("/", 1)[-1].lower()
    if (basename in (".env", "id_rsa", "id_ed25519")
            or basename.startswith(".env.")
            or basename.endswith((".p12", ".pfx"))):
        die(f"Engine backend export secret-like path rejected: {name}")
    if any(name == root or name.startswith(f"{root}/") for root in ("bin", "sbin", "lib", "usr", "etc")):
        return True
    if name in ("var", "var/lib"):
        return is_directory
    return name == "var/lib/apk" or name.startswith("var/lib/apk/")


def resolve_rootfs_link(name, linkname):
    if not isinstance(linkname, str) or not linkname or "\\" in linkname:
        die(f"Engine backend export link target is unsafe: {name}")
    parts = [] if linkname.startswith("/") else name.split("/")[:-1]
    for part in linkname.lstrip("/").split("/"):
        if part in ("", "."):
            continue
        if part == "..":
            if not parts:
                die(f"Engine backend export link escapes root: {name}")
            parts.pop()
        else:
            parts.append(part)
    target = "/".join(parts)
    if not target or not engine_backend_rootfs_member_allowed(target, False):
        die(f"Engine backend export link leaves safe roots: {name}")
    return linkname


ENGINE_BACKEND_ROOTFS_OMITTED_TOOLCHAIN_LINKS = {
    "usr/local/bin/corepack": re.compile(r"^\.\./lib/node_modules/corepack/dist/corepack\.js$"),
    "usr/local/bin/npm": re.compile(r"^\.\./lib/node_modules/npm/bin/npm-cli\.js$"),
    "usr/local/bin/npx": re.compile(r"^\.\./lib/node_modules/npm/bin/npx-cli\.js$"),
    "usr/local/bin/yarn": re.compile(r"^/opt/yarn-v[0-9]+\.[0-9]+\.[0-9]+/bin/yarn$"),
    "usr/local/bin/yarnpkg": re.compile(r"^/opt/yarn-v[0-9]+\.[0-9]+\.[0-9]+/bin/yarnpkg$"),
}


def engine_backend_rootfs_toolchain_link_is_omitted(name, linkname):
    expected = ENGINE_BACKEND_ROOTFS_OMITTED_TOOLCHAIN_LINKS.get(name)
    if expected is None:
        return False
    if not isinstance(linkname, str) or not expected.fullmatch(linkname):
        die(f"Engine backend export omitted toolchain link target mismatch: {name}")
    return True


ENGINE_BACKEND_ROOTFS_SECRET_PATTERNS = (
    re.compile(br"-----BEGIN (?:OPENSSH |RSA |EC )?PRIVATE KEY-----"),
    re.compile(br"ndc_(?:edpwb|edprb|fndbg|edppr)_[A-Za-z0-9_-]{8,}"),
    re.compile(br"AKIA[0-9A-Z]{16}"),
    re.compile(br"gh[pousr]_[A-Za-z0-9]{20,}"),
    re.compile(br"xox[baprs]-[A-Za-z0-9-]{20,}"),
)


def spool_and_scan_rootfs_file(source, name, expected_size):
    if expected_size < 0 or expected_size > MAX_FILE_BYTES:
        die(f"Engine backend export member size rejected: {name}")
    temporary = tempfile.SpooledTemporaryFile(max_size=8 * 1024 * 1024)
    total = 0
    carry = b""
    while True:
        chunk = source.read(1024 * 1024)
        if not chunk:
            break
        total += len(chunk)
        if total > MAX_FILE_BYTES:
            temporary.close()
            die(f"Engine backend export member too large: {name}")
        sample = carry + chunk
        if any(pattern.search(sample) for pattern in ENGINE_BACKEND_ROOTFS_SECRET_PATTERNS):
            temporary.close()
            die(f"Engine backend export secret material rejected: {name}")
        carry = sample[-256:]
        temporary.write(chunk)
    if total != expected_size:
        temporary.close()
        die(f"Engine backend export member size mismatch: {name}")
    temporary.seek(0)
    return temporary


def build_canonical_engine_backend_rootfs(source_tar, destination_tar):
    total_bytes = 0
    with tarfile.open(source_tar, "r:*") as source:
        members = []
        seen = set()
        source_members = {}
        for member in source.getmembers():
            name = normalize_rootfs_member_name(member.name)
            if name in seen:
                die(f"Engine backend export duplicate member: {name}")
            seen.add(name)
            source_members[name] = member
            if not engine_backend_rootfs_member_allowed(name, member.isdir()):
                continue
            if not (member.isdir() or member.isfile() or member.issym() or member.islnk()):
                die(f"Engine backend export special member rejected: {name}")
            if (member.issym()
                    and engine_backend_rootfs_toolchain_link_is_omitted(name, member.linkname)):
                continue
            members.append((name, member))
        members.sort(key=lambda item: item[0])

        with destination_tar.open("xb") as raw_output:
            with tarfile.open(fileobj=raw_output, mode="w", format=tarfile.GNU_FORMAT) as output:
                for name, member in members:
                    info = tarfile.TarInfo(name)
                    info.uid = member.uid
                    info.gid = member.gid
                    info.uname = ""
                    info.gname = ""
                    info.mode = member.mode & 0o7777
                    info.mtime = 0
                    if member.isdir():
                        info.type = tarfile.DIRTYPE
                        info.size = 0
                        output.addfile(info)
                        continue
                    if member.issym():
                        info.type = tarfile.SYMTYPE
                        info.linkname = resolve_rootfs_link(name, member.linkname)
                        info.size = 0
                        output.addfile(info)
                        continue
                    if member.islnk():
                        target_name = normalize_rootfs_member_name(member.linkname.lstrip("/"))
                        target = source_members.get(target_name)
                        if (target is None
                                or not target.isfile()
                                or not engine_backend_rootfs_member_allowed(target_name, False)):
                            die(f"Engine backend export hardlink target mismatch: {name}")
                        expected_size = target.size
                        source_member = target
                    else:
                        expected_size = member.size
                        source_member = member
                    source_file = source.extractfile(source_member)
                    if source_file is None:
                        die(f"Engine backend export member is unreadable: {name}")
                    with source_file:
                        staged = spool_and_scan_rootfs_file(source_file, name, expected_size)
                    with staged:
                        info.type = tarfile.REGTYPE
                        info.size = expected_size
                        output.addfile(info, staged)
                    total_bytes += expected_size
                    if total_bytes > MAX_PAYLOAD_BYTES:
                        die("Engine backend canonical rootfs exceeds size limit")
    destination_tar.chmod(0o600)
    return sha256_file(destination_tar)


def atomic_write_root_file(path, data, mode=0o600):
    path.parent.mkdir(parents=True, exist_ok=True)
    directory_stat = path.parent.lstat()
    if (stat.S_ISLNK(directory_stat.st_mode)
            or not stat.S_ISDIR(directory_stat.st_mode)
            or directory_stat.st_uid != 0
            or directory_stat.st_gid != 0
            or stat.S_IMODE(directory_stat.st_mode) != 0o700):
        die(f"runtime directory is unsafe: {path.parent}")
    temporary = path.with_name(f".{path.name}.{os.getpid()}.{time.time_ns()}.tmp")
    descriptor = None
    try:
        descriptor = os.open(str(temporary), os.O_WRONLY | os.O_CREAT | os.O_EXCL, mode)
        os.write(descriptor, data)
        os.fsync(descriptor)
        os.fchown(descriptor, 0, 0)
        os.fchmod(descriptor, mode)
        os.close(descriptor)
        descriptor = None
        os.replace(temporary, path)
        fsync_directory(path.parent)
    finally:
        if descriptor is not None:
            os.close(descriptor)
        if temporary.exists():
            temporary.unlink()


def ensure_root_runtime_directory(path):
    try:
        path_stat = path.lstat()
    except FileNotFoundError:
        path.mkdir(parents=True, exist_ok=False)
        path_stat = path.lstat()
    if stat.S_ISLNK(path_stat.st_mode) or not stat.S_ISDIR(path_stat.st_mode):
        die(f"runtime directory is unsafe: {path}")
    os.chown(path, 0, 0)
    path.chmod(0o700)


def prepare_engine_credential_backend_runtime():
    preflight = preflight_engine_credential_backend_runtime()
    installed_template = component_root("engine") / ENGINE_CREDENTIAL_BACKEND_OVERRIDE_TEMPLATE_REL
    try:
        template_stat = installed_template.lstat()
        template = installed_template.read_text(encoding="utf-8")
    except (FileNotFoundError, OSError, UnicodeDecodeError):
        die("installed Engine backend immutable runtime template is unreadable")
    if (stat.S_ISLNK(template_stat.st_mode)
            or not stat.S_ISREG(template_stat.st_mode)
            or template != expected_engine_credential_backend_override()):
        die("installed Engine backend immutable runtime template mismatch")

    ensure_root_runtime_directory(ENGINE_CREDENTIAL_BACKEND_RUNTIME_DIR)
    if preflight["mode"] in ("verified-derived-retry", "verified-prepared-not-active"):
        validate_engine_backend_activation_marker()
        validate_engine_backend_runtime_override_file()
        metadata = read_engine_backend_runtime_metadata()
        image = inspect_engine_backend_derived_image(metadata)
        if engine_backend_tool_versions(image_ref=ENGINE_CREDENTIAL_BACKEND_IMAGE) != metadata["tools"]:
            die("Engine backend immutable runtime tool drift detected")
        return metadata
    if preflight["mode"] == "recoverable-prepared-partial":
        quarantine_engine_backend_partial_runtime()
        return prepare_engine_credential_backend_runtime()

    with tempfile.TemporaryDirectory(prefix="engine-backend-runtime-", dir=TMP_DIR) as temporary_name:
        temporary = Path(temporary_name)
        raw_export = temporary / "container-export.tar"
        canonical_rootfs = temporary / "canonical-rootfs.tar"
        export = subprocess.run(
            [str(DOCKER), "container", "export", "--output", str(raw_export), preflight["container_id"]],
            check=False,
            stdin=subprocess.DEVNULL,
            stdout=subprocess.DEVNULL,
            stderr=subprocess.DEVNULL,
            timeout=300,
        )
        if export.returncode != 0:
            die("Engine backend container export failed")
        rootfs_sha256 = build_canonical_engine_backend_rootfs(raw_export, canonical_rootfs)
        raw_export.unlink()
        dockerfile = "\n".join((
            "FROM scratch",
            "ADD canonical-rootfs.tar /",
            "LABEL org.nodedc.release=\"credential-sink-20260716-001\"",
            f"LABEL org.nodedc.source-image-id=\"{preflight['source_image_id']}\"",
            f"LABEL org.nodedc.rootfs-sha256=\"{rootfs_sha256}\"",
            f"LABEL org.nodedc.package-lock-sha256=\"{ENGINE_CREDENTIAL_BACKEND_PACKAGE_LOCK_SHA256}\"",
            "WORKDIR /app",
            "CMD [\"/usr/local/bin/node\",\"server/index.js\"]",
            "",
        ))
        (temporary / "Dockerfile").write_text(dockerfile, encoding="utf-8")
        (temporary / "Dockerfile").chmod(0o600)
        image = ensure_engine_backend_release_image(
            temporary,
            preflight["source_image_id"],
            rootfs_sha256,
            preflight["tools"],
        )
        tools = preflight["tools"]

        os.chown(canonical_rootfs, 0, 0)
        canonical_rootfs.chmod(0o600)
        os.replace(canonical_rootfs, ENGINE_CREDENTIAL_BACKEND_ROOTFS_FILE)
        fsync_directory(ENGINE_CREDENTIAL_BACKEND_RUNTIME_DIR)

    atomic_write_root_file(
        ENGINE_CREDENTIAL_BACKEND_OVERRIDE_FILE,
        template.encode("utf-8"),
    )
    override_sha256 = validate_engine_backend_runtime_override_file()
    metadata = {
        "schemaVersion": "nodedc.engine-backend-immutable-runtime/v1",
        "release": "credential-sink-20260716-001",
        "sourceContainerId": preflight["container_id"],
        "sourceImageId": preflight["source_image_id"],
        "derivedImageId": image["Id"],
        "rootfsSha256": rootfs_sha256,
        "packageLockSha256": ENGINE_CREDENTIAL_BACKEND_PACKAGE_LOCK_SHA256,
        "nodeModulesTreeSha256": preflight["node_modules_tree_sha256"],
        "overrideSha256": override_sha256,
        "tools": tools,
    }
    atomic_write_root_file(
        ENGINE_CREDENTIAL_BACKEND_METADATA_FILE,
        (json.dumps(metadata, ensure_ascii=False, indent=2, sort_keys=True) + "\n").encode("utf-8"),
    )
    read_engine_backend_runtime_metadata()
    atomic_write_root_file(
        ENGINE_CREDENTIAL_BACKEND_ACTIVATION_FILE,
        f"sha256:{sha256_file(ENGINE_CREDENTIAL_BACKEND_METADATA_FILE)}\n".encode("ascii"),
    )
    validate_engine_backend_activation_marker()
    return metadata


def preflight_engine_credential_sink_ready():
    url = "http://127.0.0.1:3001/internal/engine-credential-sink/v1/health"
    try:
        request = urllib.request.Request(url, headers={"Cache-Control": "no-store"})
        with NO_REDIRECT_OPENER.open(request, timeout=10) as response:
            if response.status != 200:
                die(f"Engine credential sink preflight failed: HTTP {response.status}")
            body = response.read(16 * 1024)
    except urllib.error.HTTPError as exc:
        die(f"Engine credential sink preflight failed: HTTP {exc.code}")
    except Exception as exc:
        die(f"Engine credential sink preflight failed: {type(exc).__name__}")
    try:
        value = json.loads(body)
    except (UnicodeDecodeError, json.JSONDecodeError):
        die("Engine credential sink preflight returned invalid JSON")
    if (value.get("ok") is not True
            or value.get("ready") is not True
            or value.get("service") != "NDC Engine Credential Sink"
            or value.get("issuer") != {
                "serviceId": "platform.engine-credential-provisioner",
                "keyId": ENGINE_CREDENTIAL_PROVISIONER_KEY_ID,
            }):
        die("Engine credential sink preflight identity/readiness mismatch")


def engine_n8n_container_ids():
    result = subprocess.run(
        [*compose_base_cmd("engine"), "ps", "-q", "n8n"],
        cwd=str(component_compose_root("engine")),
        check=False,
        capture_output=True,
        text=True,
    )
    if result.returncode != 0:
        die("Engine n8n container lookup failed")
    container_ids = [line.strip() for line in result.stdout.splitlines() if line.strip()]
    if len(container_ids) != 1:
        die(f"Engine n8n topology mismatch: expected=1 actual={len(container_ids)}")
    return container_ids


def inspect_engine_n8n_base_image():
    images = docker_json(["image", "inspect", ENGINE_N8N_BASE_IMAGE], "Engine n8n base image inspect")
    if not isinstance(images, list) or len(images) != 1 or not isinstance(images[0], dict):
        die("Engine n8n base image inspect shape mismatch")
    image = images[0]
    image_id = image.get("Id")
    if not isinstance(image_id, str) or not re.fullmatch(r"sha256:[a-f0-9]{64}", image_id):
        die("Engine n8n base image id is invalid")
    if image.get("Architecture") != ENGINE_N8N_BASE_ARCHITECTURE or image.get("Os") != "linux":
        die("Engine n8n base image platform mismatch")
    return {
        "id": image_id,
        "architecture": image.get("Architecture"),
        "repo_digests": tuple(image.get("RepoDigests") or ()),
    }


def inspect_container(container_id):
    containers = docker_json(["inspect", container_id], "Engine n8n container inspect")
    if not isinstance(containers, list) or len(containers) != 1 or not isinstance(containers[0], dict):
        die("Engine n8n container inspect shape mismatch")
    return containers[0]


def engine_n8n_version(container_id):
    result = subprocess.run(
        [str(DOCKER), "exec", container_id, "n8n", "--version"],
        check=False,
        capture_output=True,
        text=True,
        timeout=60,
    )
    version = result.stdout.strip()
    if result.returncode != 0 or version != ENGINE_N8N_VERSION:
        die("Engine n8n runtime version mismatch")
    return version


def engine_n8n_package_loader_probe_script():
    # LoadNodesAndCredentials.init() in n8n 2.3.2 initializes NODE_PATH before
    # it loads community packages. A standalone `node -e` probe must reproduce
    # that image-owned module-resolution step or peer imports such as
    # n8n-workflow fail even though the real n8n loader succeeds.
    return (
        "process.env.NODE_PATH='"
        + ENGINE_N8N_NODE_MODULES_PATH
        + "';require('module').Module._initPaths();"
        "const {PackageDirectoryLoader}=require('"
        + ENGINE_N8N_NODE_MODULES_PATH
        + "/n8n-core');"
        "(async()=>{const loader=new PackageDirectoryLoader('"
        + ENGINE_N8N_RUNTIME_PACKAGE_PATH
        + "');await loader.loadAll();process.stdout.write(JSON.stringify({packageName:loader.packageName,"
        "nodes:loader.types.nodes.map(x=>x.name),credentials:loader.types.credentials.map(x=>x.name)}))})()"
        ".catch(error=>{process.stderr.write(String(error&&error.code||'PROBE_ERROR'));process.exit(1)});"
    )


def engine_n8n_private_loader_catalog(container_id):
    container = inspect_container(container_id)
    package_mounts = [
        mount for mount in (container.get("Mounts") or ())
        if mount.get("Destination") == ENGINE_N8N_RUNTIME_PACKAGE_PATH
    ]
    if not package_mounts:
        return {"node_types": [], "credential_types": []}
    if len(package_mounts) != 1 or package_mounts[0].get("RW") is not False:
        die("Engine n8n package-loader probe found an unsafe package mount")
    script = engine_n8n_package_loader_probe_script()
    result = subprocess.run(
        [str(DOCKER), "exec", container_id, "node", "-e", script],
        check=False,
        capture_output=True,
        text=True,
        timeout=120,
    )
    if result.returncode != 0:
        raw_category = (result.stderr or "").strip().upper()
        category = raw_category if re.fullmatch(r"[A-Z0-9_]{1,64}", raw_category) else "PROBE_ERROR"
        die(f"Engine n8n package-loader probe failed: category={category}")
    try:
        catalog = json.loads(result.stdout)
    except json.JSONDecodeError:
        die("Engine n8n package-loader probe returned invalid JSON")
    require_exact_json_keys(catalog, ("packageName", "nodes", "credentials"), "Engine n8n package-loader probe")
    if catalog.get("packageName") != "n8n-nodes-ndc":
        die("Engine n8n package-loader probe package identity mismatch")
    nodes = catalog.get("nodes")
    credentials = catalog.get("credentials")
    if not isinstance(nodes, list) or not all(isinstance(value, str) for value in nodes):
        die("Engine n8n package-loader probe node set is invalid")
    if not isinstance(credentials, list) or not all(isinstance(value, str) for value in credentials):
        die("Engine n8n package-loader probe credential set is invalid")
    return {
        "node_types": [f"n8n-nodes-ndc.{value}" for value in nodes],
        "credential_types": credentials,
    }


def engine_n8n_current_state():
    descriptor = current_engine_n8n_transition_descriptor()
    if descriptor and descriptor["action"] == "activate":
        return descriptor["releaseId"], descriptor
    return "verified_inactive", descriptor


def validate_engine_n8n_base_compose_source():
    compose_path = component_root("engine") / "docker-compose.yml"
    try:
        compose = compose_path.read_text(encoding="utf-8")
    except (OSError, UnicodeDecodeError):
        die("Engine base Compose cannot be read")
    services = re.findall(r"(?m)^  ([A-Za-z0-9_-]+):\s*$", compose)
    if tuple(services) != ENGINE_BASE_COMPOSE_SERVICES:
        die("Engine base Compose exact service topology mismatch")
    match = re.search(r"(?ms)^  n8n:\s*\n(?P<body>.*?)(?=^  [A-Za-z0-9_-]+:\s*$)", compose)
    if not match:
        die("Engine base Compose n8n service cannot be isolated")
    n8n_service = match.group("body")
    expected_image = "image: docker.n8n.io/n8nio/n8n:${N8N_IMAGE_TAG:-2.3.2}"
    if expected_image not in n8n_service:
        die("Engine base Compose n8n version mismatch")
    required_fragments = (
        "./n8n-data:/home/node/.n8n",
        "./nodedc-source/services/n8n/runtime-plugin:/opt/nodedc/runtime-plugin:ro",
        "n8n-postgres:",
    )
    if any(fragment not in n8n_service for fragment in required_fragments):
        die("Engine base Compose n8n persistence/runtime dependency mismatch")
    forbidden_fragments = (
        "build:",
        "N8N_CUSTOM_EXTENSIONS",
        "CUSTOM.",
        ENGINE_N8N_RUNTIME_PACKAGE_PATH,
        "N8N_USER_FOLDER",
        "N8N_COMMUNITY_PACKAGES_ENABLED",
        "N8N_COMMUNITY_PACKAGES_PREVENT_LOADING",
        "N8N_REINSTALL_MISSING_PACKAGES",
    )
    if any(fragment in n8n_service for fragment in forbidden_fragments):
        die("Engine base Compose contains a non-baseline n8n activation setting")


def preflight_engine_n8n_transition(descriptor, enforce_expected_current):
    validate_engine_n8n_base_compose_source()
    if descriptor["action"] == "activate":
        validate_engine_n8n_staged_release(descriptor)
    base_image = inspect_engine_n8n_base_image()
    container_id = engine_n8n_container_ids()[0]
    container = inspect_container(container_id)
    state = container.get("State") or {}
    if state.get("Status") != "running":
        die("Engine n8n baseline container is not running")
    if container.get("Image") != base_image["id"]:
        die("Engine n8n running image does not match the local 2.3.2 base image")
    version = engine_n8n_version(container_id)
    current_state, current_descriptor = engine_n8n_current_state()
    state_matches = current_state == descriptor["expectedCurrent"]
    current_catalog = engine_n8n_private_loader_catalog(container_id)
    current_types = current_catalog["node_types"]
    current_credentials = current_catalog["credential_types"]
    expected_current_types = list(ENGINE_N8N_NODE_TYPES) if current_state != "verified_inactive" else []
    expected_current_credentials = (
        list(engine_n8n_credential_types_for_release(current_state))
        if current_state != "verified_inactive"
        else []
    )
    if current_types != expected_current_types:
        die("Engine n8n current live private-node set does not match its transition state")
    if current_credentials != expected_current_credentials:
        die("Engine n8n current live private-credential set does not match its transition state")
    catalog_descriptor = (
        current_descriptor
        if current_state != "verified_inactive" and current_descriptor is not None
        else inactive_engine_n8n_descriptor(descriptor)
    )
    validate_engine_n8n_catalog_payload(component_root("engine"), catalog_descriptor)
    if enforce_expected_current and not state_matches:
        die(
            "Engine n8n transition stale current state: "
            f"expected={descriptor['expectedCurrent']} actual={current_state}"
        )
    return {
        "base_image_id": base_image["id"],
        "base_image_architecture": base_image["architecture"],
        "base_image_repo_digests": base_image["repo_digests"],
        "container_id": container_id,
        "current_state": current_state,
        "current_types": current_types,
        "current_credentials": current_credentials,
        "n8n_version": version,
        "state_matches": state_matches,
    }


def add_engine_n8n_sealed_member_paths(expected_paths, member_name):
    parts = PurePosixPath(member_name).parts
    if not parts or parts[0] != "package":
        die("Engine sealed n8n package member root mismatch")
    for depth in range(1, len(parts) + 1):
        expected_paths.add(PurePosixPath(*parts[:depth]).as_posix())


def validate_engine_n8n_sealed_release(release_dir, staged_release_dir, descriptor):
    if release_dir.is_symlink() or not release_dir.is_dir():
        die("Engine sealed n8n release is missing or unsafe")
    for filename in ("package.tgz", "release.json", "rollback.json"):
        installed = release_dir / filename
        staged = staged_release_dir / filename
        if installed.is_symlink() or not installed.is_file():
            die(f"Engine sealed n8n release member is unsafe: {filename}")
        if sha256_file(installed) != sha256_file(staged):
            die(f"Engine sealed n8n release member mismatch: {filename}")
    package_root = release_dir / "package"
    if package_root.is_symlink() or not package_root.is_dir():
        die("Engine sealed n8n package tree is missing or unsafe")
    expected_paths = {"package", "package.tgz", "release.json", "rollback.json"}
    with tarfile.open(staged_release_dir / "package.tgz", "r:gz") as archive:
        for member in archive:
            # npm package tarballs do not have to carry explicit directory
            # members. Extraction still creates those parent directories, so
            # they are part of the exact sealed tree rather than unexpected
            # content.
            add_engine_n8n_sealed_member_paths(expected_paths, member.name)
            target = release_dir.joinpath(*PurePosixPath(member.name).parts)
            target_stat = target.lstat()
            if stat.S_ISLNK(target_stat.st_mode):
                die(f"Engine sealed n8n package symlink rejected: {member.name}")
            if member.isdir():
                if not stat.S_ISDIR(target_stat.st_mode):
                    die(f"Engine sealed n8n package directory mismatch: {member.name}")
            else:
                if not stat.S_ISREG(target_stat.st_mode) or target_stat.st_size != member.size:
                    die(f"Engine sealed n8n package file mismatch: {member.name}")
                source = archive.extractfile(member)
                if source is None:
                    die(f"Engine sealed n8n package file unreadable: {member.name}")
                import hashlib
                expected_sha = hashlib.sha256(source.read()).hexdigest()
                if sha256_file(target) != expected_sha:
                    die(f"Engine sealed n8n package content mismatch: {member.name}")
    actual_paths = {
        path.relative_to(release_dir).as_posix()
        for path in release_dir.rglob("*")
    }
    if actual_paths != expected_paths:
        die("Engine sealed n8n release tree exact member set mismatch")
    for path in [release_dir, *release_dir.rglob("*")]:
        path_stat = path.lstat()
        if path_stat.st_uid != 0 or path_stat.st_gid != 0:
            die(f"Engine sealed n8n release ownership mismatch: {path}")
        expected_mode = 0o555 if stat.S_ISDIR(path_stat.st_mode) else 0o444
        if stat.S_IMODE(path_stat.st_mode) != expected_mode:
            die(f"Engine sealed n8n release mode mismatch: {path}")
    package_json = read_strict_json(package_root / "package.json", "Engine sealed n8n package.json")
    if package_json.get("name") != "n8n-nodes-ndc" or package_json.get("version") != descriptor["packageVersion"]:
        die("Engine sealed n8n package identity mismatch")


def ensure_engine_n8n_sealed_release(descriptor, current_stamp):
    staged_release_dir = validate_engine_n8n_staged_release(descriptor)
    release_parent = ENGINE_N8N_SEALED_RELEASES_ROOT / "releases" / "n8n-nodes-ndc"
    release_parent.mkdir(parents=True, exist_ok=True)
    for path in (
        ENGINE_N8N_SEALED_RELEASES_ROOT,
        ENGINE_N8N_SEALED_RELEASES_ROOT / "releases",
        release_parent,
    ):
        path_stat = path.lstat()
        if stat.S_ISLNK(path_stat.st_mode) or not stat.S_ISDIR(path_stat.st_mode):
            die(f"Engine sealed n8n release parent is unsafe: {path}")
        os.chown(path, 0, 0)
        path.chmod(0o755)
    release_dir = release_parent / descriptor["releaseId"]
    if release_dir.exists() or release_dir.is_symlink():
        validate_engine_n8n_sealed_release(release_dir, staged_release_dir, descriptor)
        return release_dir

    next_dir = release_parent / f".{descriptor['releaseId']}.next-{current_stamp}"
    if next_dir.exists() or next_dir.is_symlink():
        die(f"Engine sealed n8n release staging path already exists: {next_dir}")
    next_dir.mkdir(mode=0o700)
    for filename in ("package.tgz", "release.json", "rollback.json"):
        shutil.copy2(staged_release_dir / filename, next_dir / filename)
    with tarfile.open(staged_release_dir / "package.tgz", "r:gz") as archive:
        for member in archive:
            relative = PurePosixPath(member.name)
            target = next_dir.joinpath(*relative.parts)
            if member.isdir():
                target.mkdir(parents=True, exist_ok=True)
                continue
            target.parent.mkdir(parents=True, exist_ok=True)
            source = archive.extractfile(member)
            if source is None:
                die(f"Engine sealed n8n package member unreadable: {member.name}")
            with target.open("xb") as output:
                shutil.copyfileobj(source, output)
    for path in [next_dir, *next_dir.rglob("*")]:
        path_stat = path.lstat()
        if stat.S_ISLNK(path_stat.st_mode):
            die(f"Engine sealed n8n release symlink rejected: {path}")
        os.chown(path, 0, 0)
        if stat.S_ISDIR(path_stat.st_mode):
            path.chmod(0o555)
        elif stat.S_ISREG(path_stat.st_mode):
            path.chmod(0o444)
        else:
            die(f"Engine sealed n8n release special member rejected: {path}")
    if release_dir.exists() or release_dir.is_symlink():
        die("Engine sealed n8n release appeared concurrently")
    next_dir.rename(release_dir)
    validate_engine_n8n_sealed_release(release_dir, staged_release_dir, descriptor)
    return release_dir


def wait_engine_n8n_readiness(container_id):
    script = (
        "const http=require('http');const req=http.get('http://127.0.0.1:5678/healthz/readiness',"
        "r=>{r.resume();process.exit(r.statusCode===200?0:1)});req.on('error',()=>process.exit(1));"
        "req.setTimeout(4000,()=>{req.destroy();process.exit(1)});"
    )
    for _attempt in range(1, 61):
        result = subprocess.run(
            [str(DOCKER), "exec", container_id, "node", "-e", script],
            check=False,
            capture_output=True,
            text=True,
            timeout=10,
        )
        if result.returncode == 0:
            return
        time.sleep(5)
    die("Engine n8n readiness check failed")


def accept_engine_n8n_runtime(descriptor):
    base_image = inspect_engine_n8n_base_image()
    container_id = engine_n8n_container_ids()[0]
    container = inspect_container(container_id)
    state = container.get("State") or {}
    if state.get("Status") != "running" or container.get("Image") != base_image["id"]:
        die("Engine n8n runtime image/state acceptance failed")
    wait_engine_n8n_readiness(container_id)
    engine_n8n_version(container_id)
    config = container.get("Config") or {}
    env = set(config.get("Env") or ())
    mounts = container.get("Mounts") or ()
    package_mounts = [mount for mount in mounts if mount.get("Destination") == ENGINE_N8N_RUNTIME_PACKAGE_PATH]
    if descriptor["action"] == "activate":
        expected_source = f"/volume2/nodedc-demo/{descriptor['sealedReleaseRelativePath']}"
        if len(package_mounts) != 1:
            die("Engine n8n package mount count mismatch")
        package_mount = package_mounts[0]
        if package_mount.get("Source") != expected_source or package_mount.get("RW") is not False:
            die("Engine n8n sealed package mount mismatch")
        required_env = {
            "N8N_USER_FOLDER=/home/node",
            "N8N_COMMUNITY_PACKAGES_ENABLED=true",
            "N8N_COMMUNITY_PACKAGES_PREVENT_LOADING=false",
            "N8N_REINSTALL_MISSING_PACKAGES=false",
        }
        if not required_env.issubset(env):
            die("Engine n8n package loader environment mismatch")
        labels = config.get("Labels") or {}
        if labels.get("nodedc.n8n-private-extension.release") != descriptor["releaseId"]:
            die("Engine n8n release label mismatch")
        if labels.get("nodedc.n8n-private-extension.package-sha256") != descriptor["packageSha256"]:
            die("Engine n8n package label mismatch")
    else:
        if package_mounts:
            die("Engine n8n inactive baseline still has the private package mount")
        inactive_forbidden = (
            "N8N_USER_FOLDER=",
            "N8N_COMMUNITY_PACKAGES_ENABLED=",
            "N8N_COMMUNITY_PACKAGES_PREVENT_LOADING=",
            "N8N_REINSTALL_MISSING_PACKAGES=",
        )
        if any(item.startswith(inactive_forbidden) for item in env):
            die("Engine n8n inactive baseline still has private package loader flags")
    if any(item.startswith("N8N_CUSTOM_EXTENSIONS=") or item.startswith("CUSTOM.") for item in env):
        die("Engine n8n custom extension environment is forbidden")

    started_at = str(state.get("StartedAt") or "")
    logs = subprocess.run(
        [str(DOCKER), "logs", "--since", started_at, container_id],
        check=False,
        capture_output=True,
        text=True,
        timeout=60,
    )
    if logs.returncode != 0:
        die("Engine n8n loader log inspection failed")
    scoped_logs = f"{logs.stdout}\n{logs.stderr}".lower()
    error_patterns = (
        r"n8n-nodes-ndc.{0,400}(?:cannot find|error|failed|duplicate|eacces|syntaxerror)",
        r"(?:cannot find|error loading|failed to load|duplicate|eacces|syntaxerror).{0,400}n8n-nodes-ndc",
    )
    if any(re.search(pattern, scoped_logs, re.DOTALL) for pattern in error_patterns):
        die("Engine n8n private extension loader log acceptance failed")

    expected_types = list(ENGINE_N8N_NODE_TYPES) if descriptor["action"] == "activate" else []
    expected_credentials = (
        list(engine_n8n_credential_types_for_release(descriptor["releaseId"]))
        if descriptor["action"] == "activate"
        else []
    )
    loader_catalog = engine_n8n_private_loader_catalog(container_id)
    if loader_catalog["node_types"] != expected_types:
        die("Engine n8n live package-loader node catalog acceptance failed")
    if loader_catalog["credential_types"] != expected_credentials:
        die("Engine n8n live package-loader credential catalog acceptance failed")
    validate_engine_n8n_catalog_payload(component_root("engine"), descriptor)
    first_restart_count = int(container.get("RestartCount") or 0)
    time.sleep(2)
    stable_container = inspect_container(container_id)
    if stable_container.get("State", {}).get("Status") != "running":
        die("Engine n8n container did not remain running")
    if int(stable_container.get("RestartCount") or 0) != first_restart_count:
        die("Engine n8n container restarted during acceptance")
    return {
        "container_id": container_id,
        "image_id": base_image["id"],
        "node_types": expected_types,
        "credential_types": list(descriptor["expectedCredentialTypes"]),
    }


def plan_artifact(artifact):
    validate_artifact_location(artifact)
    ensure_layout()

    sha = sha256_file(artifact)
    publish_grant_preflight = None
    node_intelligence_preflight = None
    mcp_control_plane_preflight = None
    mcp_ontology_sdk_preflight = None
    mcp_autonomy_provider_v5_preflight = None
    l2_closed_loop_preflight = None
    composite_provider_v4_preflight = None
    provider_rotating_slot_preflight = None
    provider_authority_diagnostics_preflight = None
    depttrans_zone_authority_v1_preflight = None
    provider_target_host_policy_preflight = None
    mcp_execution_profile_decoder_preflight = None
    mcp_telemetry_catalog_preflight = None
    mcp_execution_plan_materialization_preflight = None
    mcp_execution_plan_telemetry_runtime_preflight = None
    mcp_execution_plan_module_ownership_preflight = None
    mcp_normalized_identity_search_preflight = None
    mcp_l1_credential_reuse_preflight = None
    mcp_l1_credential_provenance_preflight = None
    mcp_execution_plan_sandbox_runtime_preflight = None
    mcp_gelios_items_envelope_preflight = None
    mcp_registered_execution_profiles_preflight = None
    mcp_gelios_units_items_preflight = None
    provider_catalog_preflight = None
    device_plane_postgres_preflight = None
    with tempfile.TemporaryDirectory(prefix="plan-", dir=TMP_DIR) as tmp:
        manifest, entries, payload_dir = load_artifact(artifact, Path(tmp))
        reject_terminal_engine_l2_failed_artifact(manifest, sha)
        transition_descriptor = None
        transition_preflight = None
        if is_engine_n8n_transition(manifest["component"], entries):
            transition_descriptor = read_engine_n8n_transition_descriptor(
                payload_dir / ENGINE_N8N_TRANSITION_DESCRIPTOR_REL
            )
            transition_preflight = preflight_engine_n8n_transition(
                transition_descriptor,
                enforce_expected_current=False,
            )
        if is_engine_data_product_publish_grant_slice(manifest["component"], entries):
            publish_grant_preflight = (
                preflight_engine_data_product_publish_grant_predecessor(payload_dir)
            )
        if is_engine_node_intelligence_transition(manifest["component"], entries):
            node_intelligence_preflight = preflight_engine_node_intelligence_predecessor(
                payload_dir
            )
        if is_engine_mcp_control_plane_slice(manifest["component"], entries):
            mcp_control_plane_preflight = preflight_engine_mcp_control_plane_predecessor(
                payload_dir
            )
        if is_engine_mcp_ontology_sdk_slice(manifest["component"], entries):
            mcp_ontology_sdk_preflight = preflight_engine_mcp_ontology_sdk_predecessor(
                payload_dir
            )
        if is_engine_mcp_autonomy_provider_v5_slice(manifest["component"], entries):
            mcp_autonomy_provider_v5_preflight = (
                preflight_engine_mcp_autonomy_provider_v5_predecessor(payload_dir)
            )
        if is_engine_l2_closed_loop_slice(manifest["component"], entries):
            l2_closed_loop_preflight = preflight_engine_l2_closed_loop_predecessor(
                payload_dir
            )
        if is_engine_composite_provider_v4_slice(manifest["component"], entries):
            composite_provider_v4_preflight = preflight_engine_composite_provider_v4_predecessor()
        if is_engine_provider_rotating_slot_slice(manifest["component"], entries):
            provider_rotating_slot_preflight = preflight_engine_provider_rotating_slot_predecessor()
        if is_engine_provider_authority_diagnostics_slice(manifest["component"], entries):
            provider_authority_diagnostics_preflight = (
                preflight_engine_provider_authority_diagnostics_predecessor()
            )
        if is_engine_depttrans_zone_authority_v1_slice(manifest["component"], entries):
            depttrans_zone_authority_v1_preflight = (
                preflight_engine_depttrans_zone_authority_v1_predecessor()
            )
        if is_engine_provider_target_host_policy_slice(manifest["component"], entries):
            provider_target_host_policy_preflight = (
                preflight_engine_provider_target_host_policy_predecessor()
            )
        if is_engine_mcp_execution_profile_decoder_slice(
            manifest["component"],
            entries,
        ):
            mcp_execution_profile_decoder_preflight = (
                preflight_engine_mcp_execution_profile_decoder_predecessor()
            )
        if is_engine_mcp_telemetry_catalog_slice(manifest["component"], entries):
            mcp_telemetry_catalog_preflight = (
                preflight_engine_mcp_telemetry_catalog_predecessor()
            )
        if is_engine_mcp_execution_plan_materialization_slice(
            manifest["component"],
            entries,
        ):
            mcp_execution_plan_materialization_preflight = (
                preflight_engine_mcp_execution_plan_materialization_predecessor()
            )
        if is_engine_mcp_execution_plan_telemetry_runtime_slice(
            manifest["component"],
            entries,
        ):
            mcp_execution_plan_telemetry_runtime_preflight = (
                preflight_engine_mcp_execution_plan_telemetry_runtime_predecessor()
            )
        if is_engine_mcp_execution_plan_module_ownership_slice(
            manifest["component"],
            entries,
        ):
            mcp_execution_plan_module_ownership_preflight = (
                preflight_engine_mcp_execution_plan_module_ownership_predecessor()
            )
        if is_engine_mcp_normalized_identity_search_slice(
            manifest["component"],
            entries,
        ):
            mcp_normalized_identity_search_preflight = (
                preflight_engine_mcp_normalized_identity_search_predecessor()
            )
        if is_engine_mcp_l1_credential_reuse_slice(
            manifest["component"],
            entries,
        ):
            mcp_l1_credential_reuse_preflight = (
                preflight_engine_mcp_l1_credential_reuse_predecessor()
            )
        if is_engine_mcp_l1_credential_provenance_slice(
            manifest["component"],
            entries,
        ):
            mcp_l1_credential_provenance_preflight = (
                preflight_engine_mcp_l1_credential_provenance_predecessor()
            )
        if is_engine_mcp_execution_plan_sandbox_runtime_slice(
            manifest["component"],
            entries,
        ):
            mcp_execution_plan_sandbox_runtime_preflight = (
                preflight_engine_mcp_execution_plan_sandbox_runtime_predecessor()
            )
        if is_engine_mcp_gelios_items_envelope_slice(
            manifest["component"],
            entries,
        ):
            mcp_gelios_items_envelope_preflight = (
                preflight_engine_mcp_gelios_items_envelope_predecessor()
            )
        if is_engine_mcp_registered_execution_profiles_slice(
            manifest["component"],
            entries,
        ):
            mcp_registered_execution_profiles_preflight = (
                preflight_engine_mcp_registered_execution_profiles_predecessor()
            )
        if is_engine_mcp_gelios_units_items_slice(
            manifest["component"],
            entries,
        ):
            mcp_gelios_units_items_preflight = (
                preflight_engine_mcp_gelios_units_items_predecessor()
            )
        if is_engine_provider_security_catalog_slice(manifest["component"], entries):
            provider_catalog_preflight = preflight_engine_provider_security_catalog_predecessor()
        if is_device_plane_postgres_bootstrap_slice(
            manifest["component"],
            entries,
        ):
            device_plane_postgres_preflight = (
                preflight_device_plane_postgres_bootstrap()
            )

    component = manifest["component"]
    root = component_root(component)
    compose_root = component_compose_root(component)
    services = component_services(component, entries)
    builds = component_builds(component, entries)
    touches_publish_grant = is_engine_data_product_publish_grant_slice(
        component,
        entries,
    )
    touches_composite_provider_v4 = is_engine_composite_provider_v4_slice(
        component,
        entries,
    )
    touches_provider_rotating_slot = is_engine_provider_rotating_slot_slice(
        component,
        entries,
    )
    touches_provider_authority_diagnostics = is_engine_provider_authority_diagnostics_slice(
        component,
        entries,
    )
    touches_depttrans_zone_authority_v1 = is_engine_depttrans_zone_authority_v1_slice(
        component,
        entries,
    )
    touches_provider_target_host_policy = is_engine_provider_target_host_policy_slice(
        component,
        entries,
    )
    touches_mcp_execution_profile_decoder = (
        is_engine_mcp_execution_profile_decoder_slice(
            component,
            entries,
        )
    )
    touches_mcp_telemetry_catalog = is_engine_mcp_telemetry_catalog_slice(
        component,
        entries,
    )
    touches_mcp_execution_plan_materialization = (
        is_engine_mcp_execution_plan_materialization_slice(
            component,
            entries,
        )
    )
    touches_mcp_execution_plan_telemetry_runtime = (
        is_engine_mcp_execution_plan_telemetry_runtime_slice(
            component,
            entries,
        )
    )
    touches_mcp_execution_plan_module_ownership = (
        is_engine_mcp_execution_plan_module_ownership_slice(
            component,
            entries,
        )
    )
    touches_mcp_normalized_identity_search = (
        is_engine_mcp_normalized_identity_search_slice(
            component,
            entries,
        )
    )
    touches_mcp_l1_credential_reuse = (
        is_engine_mcp_l1_credential_reuse_slice(component, entries)
    )
    touches_mcp_l1_credential_provenance = (
        is_engine_mcp_l1_credential_provenance_slice(component, entries)
    )
    touches_mcp_execution_plan_sandbox_runtime = (
        is_engine_mcp_execution_plan_sandbox_runtime_slice(component, entries)
    )
    touches_mcp_gelios_items_envelope = (
        is_engine_mcp_gelios_items_envelope_slice(component, entries)
    )
    touches_mcp_registered_execution_profiles = (
        is_engine_mcp_registered_execution_profiles_slice(component, entries)
    )
    touches_mcp_gelios_units_items = (
        is_engine_mcp_gelios_units_items_slice(component, entries)
    )
    touches_agent_grant_migration = is_engine_agent_full_grant_migration_slice(
        component,
        entries,
    )
    publish_grant_predecessor_sha256 = None
    agent_grant_migration_predecessor_sha256 = None
    credential_backend_preflight = None
    if (
        touches_engine_credential_sink(component, entries)
        or touches_publish_grant
        or touches_composite_provider_v4
        or touches_provider_rotating_slot
        or touches_provider_authority_diagnostics
        or touches_depttrans_zone_authority_v1
        or touches_provider_target_host_policy
        or touches_mcp_execution_profile_decoder
        or touches_mcp_telemetry_catalog
        or touches_mcp_execution_plan_materialization
        or touches_mcp_execution_plan_telemetry_runtime
        or touches_mcp_execution_plan_module_ownership
        or touches_mcp_normalized_identity_search
        or touches_mcp_l1_credential_reuse
        or touches_mcp_l1_credential_provenance
        or touches_mcp_execution_plan_sandbox_runtime
        or touches_mcp_gelios_items_envelope
        or touches_mcp_registered_execution_profiles
        or touches_mcp_gelios_units_items
        or touches_agent_grant_migration
    ):
        credential_backend_preflight = preflight_engine_credential_backend_runtime()
    if touches_publish_grant:
        if publish_grant_preflight is None:
            die("Engine data product publish grant preflight is missing")
        publish_grant_predecessor_sha256 = publish_grant_preflight["compose_sha256"]
        if credential_backend_preflight["mode"] != "verified-derived-retry":
            die("Engine data product publish grant requires the active immutable credential backend")
    if touches_composite_provider_v4:
        if composite_provider_v4_preflight is None:
            die("Engine composite provider v4 preflight is missing")
        if credential_backend_preflight["mode"] != "verified-derived-retry":
            die("Engine composite provider v4 requires the active immutable credential backend")
    if touches_provider_rotating_slot:
        if provider_rotating_slot_preflight is None:
            die("Engine provider rotating slot preflight is missing")
        if credential_backend_preflight["mode"] != "verified-derived-retry":
            die("Engine provider rotating slot requires the active immutable credential backend")
    if touches_provider_authority_diagnostics:
        if provider_authority_diagnostics_preflight is None:
            die("Engine provider authority diagnostics preflight is missing")
        if credential_backend_preflight["mode"] != "verified-derived-retry":
            die("Engine provider authority diagnostics requires the active immutable credential backend")
    if touches_depttrans_zone_authority_v1:
        if depttrans_zone_authority_v1_preflight is None:
            die("Engine Depttrans zone authority v1 preflight is missing")
        if credential_backend_preflight["mode"] != "verified-derived-retry":
            die("Engine Depttrans zone authority v1 requires the active immutable credential backend")
    if touches_provider_target_host_policy:
        if provider_target_host_policy_preflight is None:
            die("Engine provider target host policy preflight is missing")
        if credential_backend_preflight["mode"] != "verified-derived-retry":
            die("Engine provider target host policy requires the active immutable credential backend")
    if touches_mcp_execution_profile_decoder:
        if mcp_execution_profile_decoder_preflight is None:
            die("Engine MCP execution profile decoder preflight is missing")
        if credential_backend_preflight["mode"] != "verified-derived-retry":
            die(
                "Engine MCP execution profile decoder requires the active "
                "immutable credential backend"
            )
    if touches_mcp_telemetry_catalog:
        if mcp_telemetry_catalog_preflight is None:
            die("Engine MCP telemetry catalog preflight is missing")
        if credential_backend_preflight["mode"] != "verified-derived-retry":
            die(
                "Engine MCP telemetry catalog requires the active immutable "
                "credential backend"
            )
    if touches_mcp_execution_plan_materialization:
        if mcp_execution_plan_materialization_preflight is None:
            die("Engine MCP execution plan materialization preflight is missing")
        if credential_backend_preflight["mode"] != "verified-derived-retry":
            die(
                "Engine MCP execution plan materialization requires the active "
                "immutable credential backend"
            )
    if touches_mcp_execution_plan_telemetry_runtime:
        if mcp_execution_plan_telemetry_runtime_preflight is None:
            die(
                "Engine MCP execution plan telemetry runtime preflight is "
                "missing"
            )
        if credential_backend_preflight["mode"] != "verified-derived-retry":
            die(
                "Engine MCP execution plan telemetry runtime requires the "
                "active immutable credential backend"
            )
    if touches_mcp_execution_plan_module_ownership:
        if mcp_execution_plan_module_ownership_preflight is None:
            die(
                "Engine MCP execution plan module ownership preflight is "
                "missing"
            )
        if credential_backend_preflight["mode"] != "verified-derived-retry":
            die(
                "Engine MCP execution plan module ownership requires the "
                "active immutable credential backend"
            )
    if touches_mcp_normalized_identity_search:
        if mcp_normalized_identity_search_preflight is None:
            die("Engine MCP normalized identity search preflight is missing")
        if credential_backend_preflight["mode"] != "verified-derived-retry":
            die(
                "Engine MCP normalized identity search requires the active "
                "immutable credential backend"
            )
    if touches_mcp_l1_credential_reuse:
        if mcp_l1_credential_reuse_preflight is None:
            die("Engine MCP L1 credential reuse preflight is missing")
        if credential_backend_preflight["mode"] != "verified-derived-retry":
            die(
                "Engine MCP L1 credential reuse requires the active immutable "
                "credential backend"
            )
    if touches_mcp_l1_credential_provenance:
        if mcp_l1_credential_provenance_preflight is None:
            die("Engine MCP L1 credential provenance preflight is missing")
        if credential_backend_preflight["mode"] != "verified-derived-retry":
            die(
                "Engine MCP L1 credential provenance requires the active "
                "immutable credential backend"
            )
    if touches_mcp_execution_plan_sandbox_runtime:
        if mcp_execution_plan_sandbox_runtime_preflight is None:
            die(
                "Engine MCP execution plan sandbox runtime preflight is "
                "missing"
            )
        if credential_backend_preflight["mode"] != "verified-derived-retry":
            die(
                "Engine MCP execution plan sandbox runtime requires the "
                "active immutable credential backend"
            )
    if touches_mcp_gelios_items_envelope:
        if mcp_gelios_items_envelope_preflight is None:
            die("Engine MCP Gelios items envelope preflight is missing")
        if credential_backend_preflight["mode"] != "verified-derived-retry":
            die(
                "Engine MCP Gelios items envelope requires the active "
                "immutable credential backend"
            )
    if touches_mcp_registered_execution_profiles:
        if mcp_registered_execution_profiles_preflight is None:
            die(
                "Engine MCP registered execution profiles preflight is missing"
            )
        if credential_backend_preflight["mode"] != "verified-derived-retry":
            die(
                "Engine MCP registered execution profiles requires the active "
                "immutable credential backend"
            )
    if touches_mcp_gelios_units_items:
        if mcp_gelios_units_items_preflight is None:
            die("Engine MCP Gelios units items preflight is missing")
        if credential_backend_preflight["mode"] != "verified-derived-retry":
            die(
                "Engine MCP Gelios units items requires the active immutable "
                "credential backend"
            )
    if touches_agent_grant_migration:
        agent_grant_migration_predecessor_sha256 = (
            preflight_engine_agent_full_grant_migration_predecessor()
        )
        if credential_backend_preflight["mode"] != "verified-derived-retry":
            die("Engine agent full grant migration requires the active immutable credential backend")
    print("== plan ==")
    print(f"artifact={artifact.name}")
    print(f"sha256={sha}")
    print(f"id={manifest['id']}")
    print(f"component={component}")
    print(f"type={manifest['type']}")
    print(f"payload_root={root}")
    print(f"compose_root={compose_root}")
    compose_project = component_compose_project(component)
    if compose_project:
        print(f"compose_project={compose_project}")
    for build_root, build_args in builds:
        print(f"build_root={build_root}")
        print(f"build={' '.join((str(DOCKER),) + tuple(build_args))}")
    print(f"services={' '.join(services)}")
    if l2_closed_loop_preflight:
        descriptor = l2_closed_loop_preflight["descriptor"]
        print(
            "engine_l2_transition="
            f"{l2_closed_loop_preflight['mode']}"
        )
        print(
            "failed_patch="
            f"{ENGINE_L2_CLOSED_LOOP_FAILED_PATCH_ID}"
        )
        print(
            "failed_artifact_sha256="
            f"{ENGINE_L2_CLOSED_LOOP_FAILED_ARTIFACT_SHA256}"
        )
        print(
            "recovery_backup="
            f"{l2_closed_loop_preflight['recovery_backup'].name}"
        )
        print(
            "predecessor_gateway_sha256="
            f"{l2_closed_loop_preflight['predecessor_gateway_sha256']}"
        )
        print(
            "partial_gateway_sha256="
            f"{l2_closed_loop_preflight['partial_gateway_sha256']}"
        )
        print(
            "target_gateway_sha256="
            f"{l2_closed_loop_preflight['target_gateway_sha256']}"
        )
        print(
            "predecessor_descriptor_sha256="
            f"{ENGINE_L2_CLOSED_LOOP_PARTIAL_SHA256[ENGINE_L2_CLOSED_LOOP_DESCRIPTOR_REL]}"
        )
        print(
            "target_descriptor_sha256="
            f"{ENGINE_L2_CLOSED_LOOP_TARGET_SHA256[ENGINE_L2_CLOSED_LOOP_DESCRIPTOR_REL]}"
        )
        print(f"node_intelligence_release={descriptor['releaseId']}")
        print(
            "backend_current_barrier="
            f"{l2_closed_loop_preflight['backend_mode']}"
        )
        print(
            "backend_source_container_id="
            f"{l2_closed_loop_preflight['backend_container_id']}"
        )
        print(
            "app_source_container_id="
            f"{l2_closed_loop_preflight['app_container_id']}"
        )
        print("node_intelligence_image=preserved")
        print("backend_force_recreate=yes")
        print("app_force_recreate=yes")
        print("backend_pull=never")
        print("n8n_l1_l2_data=preserved")
        print("credentials=preserved")
        print("databases=preserved")
        print("ai_workspace=untouched")
    if node_intelligence_preflight:
        descriptor = node_intelligence_preflight["descriptor"]
        print(f"node_intelligence_transition={descriptor['action']}")
        print(f"node_intelligence_release={descriptor['releaseId']}")
        print(f"node_intelligence_current_state={node_intelligence_preflight['current_state']}")
        print(f"node_intelligence_upstream_commit={descriptor['upstream']['commit']}")
        print(f"node_intelligence_image={descriptor['image']['tag']}")
        print(f"node_intelligence_image_config_sha256={descriptor['image']['configSha256']}")
        if descriptor["action"] == "activate":
            print(f"node_intelligence_image_archive_sha256={descriptor['image']['archiveSha256']}")
        print("node_intelligence_build=offline-image-load")
        print("node_intelligence_pull=never")
        print(f"node_intelligence_secret=runner-managed:{ENGINE_NODE_INTELLIGENCE_SECRET_FILE}")
        print("node_intelligence_host_ports=none")
        print(f"predecessor_gateway_sha256={node_intelligence_preflight['gateway_sha256']}")
        print(f"backend_current_barrier={node_intelligence_preflight['backend_mode']}")
    if mcp_control_plane_preflight:
        print("engine_mcp_transition=managed-reader-grant+validator-reconciliation")
        print("engine_mcp_version=0.5.0")
        print("engine_mcp_installer=0.1.4")
        print("engine_mcp_reader_grant=plan+apply+accept+rollback")
        print(
            "predecessor_gateway_sha256="
            f"{mcp_control_plane_preflight['predecessor_gateway_sha256']}"
        )
        print(
            "target_gateway_sha256="
            f"{mcp_control_plane_preflight['target_gateway_sha256']}"
        )
        print(f"backend_current_barrier={mcp_control_plane_preflight['backend_mode']}")
        print("node_intelligence_image=preserved")
        print("n8n_l1=untouched")
    if mcp_ontology_sdk_preflight:
        print("engine_mcp_transition=separate-ontology+gelios-sdk-query-auth")
        print("engine_mcp_version=0.6.0")
        print("engine_mcp_installer=0.1.5")
        print("engine_mcp_ontology=separate-read-only-proxy")
        print("engine_provider_package=gelios.provider.v2")
        print("engine_provider_credential=httpQueryAuth")
        print(
            "predecessor_gateway_sha256="
            f"{mcp_ontology_sdk_preflight['predecessor_gateway_sha256']}"
        )
        print(
            "target_gateway_sha256="
            f"{mcp_ontology_sdk_preflight['target_gateway_sha256']}"
        )
        print(f"backend_current_barrier={mcp_ontology_sdk_preflight['backend_mode']}")
        print("node_intelligence_image=preserved")
        print("n8n_l1=untouched")
    if mcp_autonomy_provider_v5_preflight:
        print("engine_mcp_transition=capability-scoped-autonomy+provider-v5")
        print("engine_mcp_version=0.6.0")
        print("engine_mcp_installer=0.1.6")
        print("engine_mcp_authority=mcp-capability-intersect-user-objective")
        print("engine_mcp_plan=machine-safety-barrier")
        print("engine_mcp_retry_stop=three-identical-failures-without-new-evidence")
        print("engine_provider_packages=gelios.provider.v4,gelios.provider.v5")
        print("engine_data_product=fleet.positions.current.v4")
        print(
            "predecessor_gateway_sha256="
            f"{mcp_autonomy_provider_v5_preflight['predecessor_gateway_sha256']}"
        )
        print(
            "target_gateway_sha256="
            f"{mcp_autonomy_provider_v5_preflight['target_gateway_sha256']}"
        )
        print(f"backend_current_barrier={mcp_autonomy_provider_v5_preflight['backend_mode']}")
        print("node_intelligence_image=preserved")
        print("n8n_l1=untouched")
    if provider_catalog_preflight:
        print("engine_provider_catalog_transition=gelios-unit-profile-authority-v8")
        print("engine_provider_package=gelios.provider.v8")
        print("engine_provider_credential=ndcProviderRotatingAccessApi")
        print(
            "engine_provider_endpoint=https://api.geliospro.com/api/v1/units?"
            "incltrip=true&inclcntrs=true&inclsnsrs=true&incllsv=true"
        )
        print("engine_data_product=fleet.units.profile.current.v1")
        print(
            "predecessor_catalog_sha256="
            f"{provider_catalog_preflight['catalog_sha256']}"
        )
        print(f"target_catalog_sha256={ENGINE_PROVIDER_SECURITY_CATALOG_TARGET_SHA256}")
        print(f"backend_current_barrier={provider_catalog_preflight['backend_mode']}")
        print("n8n_l1=untouched")
        print("engine_ui=untouched")
        print("engine_databases=untouched")
        print("mcp_nginx=untouched")
    if composite_provider_v4_preflight:
        print("engine_composite_provider_transition=exact-v3-to-v4")
        print("engine_provider_package=gelios.provider.v4")
        print(
            "engine_provider_capabilities="
            "gelios.monitoring_config.current.read,gelios.units.current.read"
        )
        print("engine_provider_requests=monitoring-config,units?incltrip=true")
        print("engine_data_product=fleet.positions.current.v3")
        for changed_path in ENGINE_COMPOSITE_PROVIDER_V4_ARTIFACT_ENTRIES:
            print(f"engine_composite_provider_changed_path={changed_path}")
            print(
                f"engine_composite_provider_predecessor_sha256[{changed_path}]="
                f"{composite_provider_v4_preflight['predecessor_sha256'][changed_path]}"
            )
            print(
                f"engine_composite_provider_target_sha256[{changed_path}]="
                f"{composite_provider_v4_preflight['target_sha256'][changed_path]}"
            )
        print(f"backend_current_barrier={composite_provider_v4_preflight['backend_mode']}")
        print("provider_credential_values=preserved")
        print("backend_force_recreate=yes")
        print("backend_pull=never")
        print("n8n_l1=untouched")
        print("engine_ui=untouched")
        print("engine_databases=untouched")
    if provider_rotating_slot_preflight:
        print("engine_provider_credential_transition=exact-active-slot-alignment")
        print("engine_provider_package=gelios.provider.v4")
        print("engine_provider_auth_mode=gelios.rest-rotating-bearer.v3")
        print("engine_provider_credential_slot=ndcProviderRotatingAccessApi")
        print("engine_data_product=fleet.positions.current.v3")
        for changed_path in ENGINE_PROVIDER_ROTATING_SLOT_ARTIFACT_ENTRIES:
            print(f"engine_provider_rotating_slot_changed_path={changed_path}")
            print(
                f"engine_provider_rotating_slot_predecessor_sha256[{changed_path}]="
                f"{provider_rotating_slot_preflight['predecessor_sha256'][changed_path]}"
            )
            print(
                f"engine_provider_rotating_slot_target_sha256[{changed_path}]="
                f"{provider_rotating_slot_preflight['target_sha256'][changed_path]}"
            )
        print(f"backend_current_barrier={provider_rotating_slot_preflight['backend_mode']}")
        print("provider_credential_values=preserved")
        print("backend_force_recreate=yes")
        print("backend_pull=never")
        print("l2_graph=untouched")
        print("n8n_l1=untouched")
        print("engine_ui=untouched")
        print("engine_databases=untouched")
    if provider_authority_diagnostics_preflight:
        print("engine_validation_transition=private-node-name-reconciliation")
        print("engine_validation_boundary=engine-pinned-private-node-catalog")
        print("private_node_identity=node-id-or-exact-display-name")
        print("provider_credential_values=preserved")
        for changed_path in ENGINE_PROVIDER_AUTHORITY_DIAGNOSTICS_ARTIFACT_ENTRIES:
            print(f"engine_provider_authority_changed_path={changed_path}")
            print(
                f"engine_provider_authority_predecessor_sha256[{changed_path}]="
                f"{provider_authority_diagnostics_preflight['predecessor_sha256'][changed_path]}"
            )
            print(
                f"engine_provider_authority_target_sha256[{changed_path}]="
                f"{provider_authority_diagnostics_preflight['target_sha256'][changed_path]}"
            )
        print(f"backend_current_barrier={provider_authority_diagnostics_preflight['backend_mode']}")
        print("backend_force_recreate=yes")
        print("backend_pull=never")
        print("l2_graph=untouched")
        print("n8n_l1=untouched")
        print("engine_ui=untouched")
        print("engine_databases=untouched")
    if depttrans_zone_authority_v1_preflight:
        print_engine_depttrans_zone_authority_v1_plan(
            depttrans_zone_authority_v1_preflight
        )
    if provider_target_host_policy_preflight:
        print("engine_provider_transport_transition=exact-literal-target-host")
        print("engine_provider_package=gelios.provider.v4")
        print("engine_data_product=fleet.positions.current.v3")
        print("provider_credential_values=preserved")
        for changed_path in ENGINE_PROVIDER_TARGET_HOST_POLICY_ARTIFACT_ENTRIES:
            print(f"engine_provider_target_host_policy_changed_path={changed_path}")
            print(
                f"engine_provider_target_host_policy_predecessor_sha256[{changed_path}]="
                f"{provider_target_host_policy_preflight['predecessor_sha256'][changed_path]}"
            )
            print(
                f"engine_provider_target_host_policy_target_sha256[{changed_path}]="
                f"{provider_target_host_policy_preflight['target_sha256'][changed_path]}"
            )
        print(f"backend_current_barrier={provider_target_host_policy_preflight['backend_mode']}")
        print("backend_force_recreate=yes")
        print("backend_pull=never")
        print("l2_graph=untouched")
        print("n8n_l1=untouched")
        print("engine_ui=untouched")
        print("engine_databases=untouched")
    if mcp_execution_profile_decoder_preflight:
        print(
            "engine_mcp_observability_transition="
            "exact-flatted-numeric-string-preservation"
        )
        print("engine_mcp_surface=external-codex")
        print("engine_mcp_tool=engine_get_node_output_profile")
        print("engine_mcp_profile_values_included=no")
        print("engine_mcp_raw_execution_data_included=no")
        for changed_path in ENGINE_MCP_EXECUTION_PROFILE_DECODER_ARTIFACT_ENTRIES:
            print(f"engine_mcp_profile_decoder_changed_path={changed_path}")
            if changed_path in mcp_execution_profile_decoder_preflight[
                "predecessor_sha256"
            ]:
                print(
                    f"engine_mcp_profile_decoder_predecessor_sha256[{changed_path}]="
                    f"{mcp_execution_profile_decoder_preflight['predecessor_sha256'][changed_path]}"
                )
            elif changed_path in mcp_execution_profile_decoder_preflight["new_paths"]:
                print(
                    f"engine_mcp_profile_decoder_predecessor_state[{changed_path}]="
                    "absent"
                )
            else:
                die(
                    "Engine MCP execution profile decoder plan has no predecessor "
                    f"state: {changed_path}"
                )
            print(
                f"engine_mcp_profile_decoder_target_sha256[{changed_path}]="
                f"{mcp_execution_profile_decoder_preflight['target_sha256'][changed_path]}"
            )
        print(
            "backend_current_barrier="
            f"{mcp_execution_profile_decoder_preflight['backend_mode']}"
        )
        print("backend_force_recreate=yes")
        print("backend_pull=never")
        print("l2_graph=untouched")
        print("n8n_l1=untouched")
        print("engine_ui=untouched")
        print("engine_databases=untouched")
        print("mcp_nginx=untouched")
        print("embedded_ai_workspace=untouched")
    if mcp_telemetry_catalog_preflight:
        print(
            "engine_mcp_observability_transition="
            f"{mcp_telemetry_catalog_preflight['mode']}"
        )
        print("engine_mcp_version=0.8.0")
        print("engine_mcp_surface=external-codex")
        print("engine_mcp_tool=engine_get_telemetry_reading_catalog")
        print("engine_mcp_reading_values_included=no")
        print("engine_mcp_raw_execution_data_included=no")
        print("node_intelligence_descriptor=attested-gateway-successor")
        print("node_intelligence_release=2.33.2-974a9fb3492f")
        print("node_intelligence_image=preserved")
        for foundation_path, foundation_sha256 in (
            mcp_telemetry_catalog_preflight["foundation_sha256"].items()
        ):
            print(
                f"engine_mcp_telemetry_catalog_foundation_sha256[{foundation_path}]="
                f"{foundation_sha256}"
            )
        for changed_path in ENGINE_MCP_TELEMETRY_CATALOG_ARTIFACT_ENTRIES:
            print(f"engine_mcp_telemetry_catalog_changed_path={changed_path}")
            if changed_path in mcp_telemetry_catalog_preflight[
                "predecessor_sha256"
            ]:
                print(
                    f"engine_mcp_telemetry_catalog_predecessor_sha256[{changed_path}]="
                    f"{mcp_telemetry_catalog_preflight['predecessor_sha256'][changed_path]}"
                )
            elif changed_path in mcp_telemetry_catalog_preflight["new_paths"]:
                print(
                    f"engine_mcp_telemetry_catalog_predecessor_state[{changed_path}]="
                    "absent"
                )
            else:
                die(
                    "Engine MCP telemetry catalog plan has no predecessor state: "
                    f"{changed_path}"
                )
            print(
                f"engine_mcp_telemetry_catalog_target_sha256[{changed_path}]="
                f"{mcp_telemetry_catalog_preflight['target_sha256'][changed_path]}"
            )
        print(
            "backend_current_barrier="
            f"{mcp_telemetry_catalog_preflight['backend_mode']}"
        )
        print("backend_force_recreate=yes")
        print("backend_pull=never")
        print("l2_graph=untouched")
        print("n8n_l1=untouched")
        print("engine_ui=untouched")
        print("engine_databases=untouched")
        print("mcp_nginx=untouched")
        print("embedded_ai_workspace=untouched")
    if mcp_execution_plan_materialization_preflight:
        print(
            "engine_mcp_authoring_transition="
            f"{mcp_execution_plan_materialization_preflight['mode']}"
        )
        print("engine_mcp_version=0.9.0")
        print("engine_mcp_surface=external-codex")
        print(
            "engine_mcp_tool="
            "engine_plan_l2_execution_plan_materialization"
        )
        print(
            "engine_mcp_tool="
            "engine_apply_l2_execution_plan_materialization"
        )
        print("engine_mcp_provider_logic_authority=trusted-provider-package")
        print("engine_mcp_unmanaged_graph_policy=explicit-adoption-required")
        print("engine_mcp_plan_phase=read-only")
        print("engine_mcp_apply_phase=opaque-plan-ref-only")
        print("node_intelligence_descriptor=attested-gateway-successor")
        print("node_intelligence_release=2.33.2-974a9fb3492f")
        print("node_intelligence_image=preserved")
        for foundation_path, foundation_sha256 in (
            mcp_execution_plan_materialization_preflight[
                "foundation_sha256"
            ].items()
        ):
            print(
                "engine_mcp_execution_plan_materialization_foundation_sha256"
                f"[{foundation_path}]={foundation_sha256}"
            )
        for changed_path in (
            ENGINE_MCP_EXECUTION_PLAN_MATERIALIZATION_ARTIFACT_ENTRIES
        ):
            print(
                "engine_mcp_execution_plan_materialization_changed_path="
                f"{changed_path}"
            )
            if changed_path in mcp_execution_plan_materialization_preflight[
                "predecessor_sha256"
            ]:
                print(
                    "engine_mcp_execution_plan_materialization_predecessor_sha256"
                    f"[{changed_path}]="
                    f"{mcp_execution_plan_materialization_preflight['predecessor_sha256'][changed_path]}"
                )
            elif changed_path in mcp_execution_plan_materialization_preflight[
                "new_paths"
            ]:
                print(
                    "engine_mcp_execution_plan_materialization_predecessor_state"
                    f"[{changed_path}]=absent"
                )
            else:
                die(
                    "Engine MCP execution plan materialization plan has no "
                    f"predecessor state: {changed_path}"
                )
            print(
                "engine_mcp_execution_plan_materialization_target_sha256"
                f"[{changed_path}]="
                f"{mcp_execution_plan_materialization_preflight['target_sha256'][changed_path]}"
            )
        print(
            "backend_current_barrier="
            f"{mcp_execution_plan_materialization_preflight['backend_mode']}"
        )
        print("backend_force_recreate=yes")
        print("backend_pull=never")
        print("l2_graph=untouched")
        print("n8n_l1=untouched")
        print("engine_ui=untouched")
        print("engine_databases=untouched")
        print("credentials=preserved")
        print("mcp_nginx=untouched")
        print("embedded_ai_workspace=untouched")
    if mcp_execution_plan_telemetry_runtime_preflight:
        print(
            "engine_mcp_authoring_runtime_transition="
            f"{mcp_execution_plan_telemetry_runtime_preflight['mode']}"
        )
        print("engine_mcp_version=0.9.0")
        print("engine_mcp_surface=external-codex")
        print("engine_mcp_compiler_predecessor=1.1.0")
        print("engine_mcp_compiler_supported=1.1.0,1.2.0")
        print("engine_mcp_legacy_runtime_preserved=yes")
        print("engine_mcp_provider_logic_authority=trusted-provider-package")
        print(
            "engine_mcp_telemetry_authority="
            "trusted-projection+visible-declared-sensor"
        )
        print("engine_mcp_unprojected_parameters=discarded")
        print("engine_mcp_raw_provider_payload_at_publish=forbidden")
        for foundation_path, foundation_sha256 in (
            mcp_execution_plan_telemetry_runtime_preflight[
                "foundation_sha256"
            ].items()
        ):
            print(
                "engine_mcp_execution_plan_telemetry_runtime_foundation_sha256"
                f"[{foundation_path}]={foundation_sha256}"
            )
        for changed_path in (
            ENGINE_MCP_EXECUTION_PLAN_TELEMETRY_RUNTIME_ARTIFACT_ENTRIES
        ):
            print(
                "engine_mcp_execution_plan_telemetry_runtime_changed_path="
                f"{changed_path}"
            )
            if changed_path in mcp_execution_plan_telemetry_runtime_preflight[
                "predecessor_sha256"
            ]:
                print(
                    "engine_mcp_execution_plan_telemetry_runtime_predecessor_sha256"
                    f"[{changed_path}]="
                    f"{mcp_execution_plan_telemetry_runtime_preflight['predecessor_sha256'][changed_path]}"
                )
            elif changed_path in mcp_execution_plan_telemetry_runtime_preflight[
                "new_paths"
            ]:
                print(
                    "engine_mcp_execution_plan_telemetry_runtime_predecessor_state"
                    f"[{changed_path}]=absent"
                )
            else:
                die(
                    "Engine MCP execution plan telemetry runtime plan has no "
                    f"predecessor state: {changed_path}"
                )
            print(
                "engine_mcp_execution_plan_telemetry_runtime_target_sha256"
                f"[{changed_path}]="
                f"{mcp_execution_plan_telemetry_runtime_preflight['target_sha256'][changed_path]}"
            )
        print(
            "backend_current_barrier="
            f"{mcp_execution_plan_telemetry_runtime_preflight['backend_mode']}"
        )
        print("backend_force_recreate=yes")
        print("backend_pull=never")
        print("l2_graph=untouched")
        print("n8n_l1=untouched")
        print("engine_ui=untouched")
        print("engine_databases=untouched")
        print("credentials=preserved")
        print("node_intelligence_image=preserved")
        print("mcp_nginx=untouched")
        print("embedded_ai_workspace=untouched")
    if mcp_execution_plan_module_ownership_preflight:
        print(
            "engine_mcp_module_ownership_transition="
            f"{mcp_execution_plan_module_ownership_preflight['mode']}"
        )
        print("engine_mcp_version=0.10.0")
        print("engine_mcp_surface=external-codex")
        print(
            "engine_mcp_materialization_strategies="
            "create_or_reconcile_owned,adopt_existing,adopt_existing_module"
        )
        print("engine_mcp_module_node_bindings=exact-one-to-one")
        print("engine_mcp_module_retirement_boundary=closed")
        print("engine_mcp_shared_manual_webhook=compatible-config-preserved")
        print("engine_mcp_provider_credential_nodes=engine-managed")
        print("engine_mcp_publisher_nodes=engine-managed")
        print("engine_provider_package_added=gelios.provider.v9")
        print("engine_provider_package_legacy=gelios.provider.v8:preserved")
        print("node_intelligence_descriptor=attested-gateway-successor")
        print("node_intelligence_release=2.33.2-974a9fb3492f")
        print("node_intelligence_image=preserved")
        for foundation_path, foundation_sha256 in (
            mcp_execution_plan_module_ownership_preflight[
                "foundation_sha256"
            ].items()
        ):
            print(
                "engine_mcp_execution_plan_module_ownership_foundation_sha256"
                f"[{foundation_path}]={foundation_sha256}"
            )
        for changed_path in (
            ENGINE_MCP_EXECUTION_PLAN_MODULE_OWNERSHIP_ARTIFACT_ENTRIES
        ):
            print(
                "engine_mcp_execution_plan_module_ownership_changed_path="
                f"{changed_path}"
            )
            if changed_path in mcp_execution_plan_module_ownership_preflight[
                "predecessor_sha256"
            ]:
                print(
                    "engine_mcp_execution_plan_module_ownership_predecessor_sha256"
                    f"[{changed_path}]="
                    f"{mcp_execution_plan_module_ownership_preflight['predecessor_sha256'][changed_path]}"
                )
            elif changed_path in mcp_execution_plan_module_ownership_preflight[
                "new_paths"
            ]:
                print(
                    "engine_mcp_execution_plan_module_ownership_predecessor_state"
                    f"[{changed_path}]=absent"
                )
            else:
                die(
                    "Engine MCP execution plan module ownership plan has no "
                    f"predecessor state: {changed_path}"
                )
            print(
                "engine_mcp_execution_plan_module_ownership_target_sha256"
                f"[{changed_path}]="
                f"{mcp_execution_plan_module_ownership_preflight['target_sha256'][changed_path]}"
            )
        print(
            "backend_current_barrier="
            f"{mcp_execution_plan_module_ownership_preflight['backend_mode']}"
        )
        print("backend_force_recreate=yes")
        print("backend_pull=never")
        print("l2_graph=untouched")
        print("n8n_l1=untouched")
        print("engine_ui=untouched")
        print("engine_databases=untouched")
        print("credentials=preserved")
        print("mcp_nginx=untouched")
        print("embedded_ai_workspace=untouched")
    if mcp_normalized_identity_search_preflight:
        print(
            "engine_mcp_identity_transition="
            f"{mcp_normalized_identity_search_preflight['mode']}"
        )
        print("engine_mcp_version=0.11.0")
        print("engine_mcp_surface=external-codex")
        print("engine_mcp_tool=engine_find_normalized_subjects")
        print("engine_mcp_identity_values=full-authorized-admin")
        print("engine_mcp_search_authority=canonical-normalized-facts")
        print("engine_mcp_raw_execution_data_included=no")
        print("engine_mcp_raw_provider_payload_included=no")
        print("engine_mcp_command_surface_included=no")
        print("engine_mcp_compiler_added=1.4.0")
        print("engine_mcp_legacy_compilers=1.1.0,1.2.0,1.3.0:preserved")
        print("engine_provider_package_added=gelios.provider.v11")
        print("engine_data_product_added=fleet.units.identity.current.v1")
        print("node_intelligence_descriptor=attested-gateway-successor")
        print("node_intelligence_release=2.33.2-974a9fb3492f")
        print("node_intelligence_image=preserved")
        for foundation_path, foundation_sha256 in (
            mcp_normalized_identity_search_preflight[
                "foundation_sha256"
            ].items()
        ):
            print(
                "engine_mcp_normalized_identity_search_foundation_sha256"
                f"[{foundation_path}]={foundation_sha256}"
            )
        for changed_path in (
            ENGINE_MCP_NORMALIZED_IDENTITY_SEARCH_ARTIFACT_ENTRIES
        ):
            print(
                "engine_mcp_normalized_identity_search_changed_path="
                f"{changed_path}"
            )
            if changed_path in mcp_normalized_identity_search_preflight[
                "predecessor_sha256"
            ]:
                print(
                    "engine_mcp_normalized_identity_search_predecessor_sha256"
                    f"[{changed_path}]="
                    f"{mcp_normalized_identity_search_preflight['predecessor_sha256'][changed_path]}"
                )
            elif changed_path in mcp_normalized_identity_search_preflight[
                "new_paths"
            ]:
                print(
                    "engine_mcp_normalized_identity_search_predecessor_state"
                    f"[{changed_path}]=absent"
                )
            else:
                die(
                    "Engine MCP normalized identity search plan has no "
                    f"predecessor state: {changed_path}"
                )
            print(
                "engine_mcp_normalized_identity_search_target_sha256"
                f"[{changed_path}]="
                f"{mcp_normalized_identity_search_preflight['target_sha256'][changed_path]}"
            )
        print(
            "backend_current_barrier="
            f"{mcp_normalized_identity_search_preflight['backend_mode']}"
        )
        print("backend_force_recreate=yes")
        print("backend_pull=never")
        print("l2_graph=untouched")
        print("n8n_l1=untouched")
        print("engine_ui=untouched")
        print("engine_databases=untouched")
        print("credentials=preserved")
        print("mcp_nginx=untouched")
        print("embedded_ai_workspace=untouched")
    if mcp_l1_credential_reuse_preflight:
        print(
            "engine_mcp_l1_credential_reuse_transition="
            f"{mcp_l1_credential_reuse_preflight['mode']}"
        )
        print("engine_mcp_version=0.11.0")
        print("engine_mcp_surface=external-codex")
        print("engine_mcp_tool=engine_list_l2_credential_refs")
        print("engine_mcp_apply_operation=assignCredentialRef")
        print("engine_mcp_credential_scope=same-l1-workflow")
        print("engine_mcp_visibility_proof=local-registry-provenance")
        print("engine_mcp_cross_l1_sharing=no")
        print("engine_mcp_managed_grants=target-local")
        print("engine_mcp_native_credential_ids_included=no")
        print("engine_mcp_logical_credential_ids_included=no")
        print("engine_mcp_credential_values_included=no")
        print("engine_mcp_transport_https_required=yes")
        print("engine_mcp_transport_redirects_disabled=yes")
        for foundation_path, foundation_sha256 in (
            mcp_l1_credential_reuse_preflight["foundation_sha256"].items()
        ):
            print(
                "engine_mcp_l1_credential_reuse_foundation_sha256"
                f"[{foundation_path}]={foundation_sha256}"
            )
        for changed_path in ENGINE_MCP_L1_CREDENTIAL_REUSE_ARTIFACT_ENTRIES:
            print(
                "engine_mcp_l1_credential_reuse_changed_path="
                f"{changed_path}"
            )
            if changed_path in mcp_l1_credential_reuse_preflight[
                "predecessor_sha256"
            ]:
                print(
                    "engine_mcp_l1_credential_reuse_predecessor_sha256"
                    f"[{changed_path}]="
                    f"{mcp_l1_credential_reuse_preflight['predecessor_sha256'][changed_path]}"
                )
            elif changed_path in mcp_l1_credential_reuse_preflight["new_paths"]:
                print(
                    "engine_mcp_l1_credential_reuse_predecessor_state"
                    f"[{changed_path}]=absent"
                )
            else:
                die(
                    "Engine MCP L1 credential reuse plan has no predecessor "
                    f"state: {changed_path}"
                )
            print(
                "engine_mcp_l1_credential_reuse_target_sha256"
                f"[{changed_path}]="
                f"{mcp_l1_credential_reuse_preflight['target_sha256'][changed_path]}"
            )
        print(
            "backend_current_barrier="
            f"{mcp_l1_credential_reuse_preflight['backend_mode']}"
        )
        print("backend_force_recreate=yes")
        print("backend_pull=never")
        print("l2_graph=untouched")
        print("n8n_l1=untouched")
        print("engine_ui=untouched")
        print("engine_databases=untouched")
        print("credentials=preserved")
        print("mcp_nginx=untouched")
        print("embedded_ai_workspace=untouched")
    if mcp_l1_credential_provenance_preflight:
        print(
            "engine_mcp_l1_credential_provenance_transition="
            f"{mcp_l1_credential_provenance_preflight['mode']}"
        )
        print("engine_mcp_version=0.11.0")
        print("engine_mcp_surface=external-codex")
        print("engine_mcp_tool=engine_list_l2_credential_refs")
        print("engine_mcp_apply_operation=assignCredentialRef")
        print("engine_mcp_credential_scope=same-l1-workflow")
        print(
            "engine_mcp_local_provenance_sources="
            "manual,workflow-ref,credentials-file"
        )
        print("engine_mcp_referenced_source_requires_sync_payload=yes")
        print("engine_mcp_logical_key_equality_required=yes")
        print("engine_mcp_cross_l1_sharing=no")
        print("engine_mcp_managed_grants=target-local")
        print("engine_mcp_credential_ids_included=no")
        print("engine_mcp_credential_values_included=no")
        for foundation_path, foundation_sha256 in (
            mcp_l1_credential_provenance_preflight[
                "foundation_sha256"
            ].items()
        ):
            print(
                "engine_mcp_l1_credential_provenance_foundation_sha256"
                f"[{foundation_path}]={foundation_sha256}"
            )
        for changed_path in (
            ENGINE_MCP_L1_CREDENTIAL_PROVENANCE_ARTIFACT_ENTRIES
        ):
            print(
                "engine_mcp_l1_credential_provenance_changed_path="
                f"{changed_path}"
            )
            if changed_path in mcp_l1_credential_provenance_preflight[
                "predecessor_sha256"
            ]:
                print(
                    "engine_mcp_l1_credential_provenance_predecessor_sha256"
                    f"[{changed_path}]="
                    f"{mcp_l1_credential_provenance_preflight['predecessor_sha256'][changed_path]}"
                )
            elif changed_path in mcp_l1_credential_provenance_preflight[
                "new_paths"
            ]:
                print(
                    "engine_mcp_l1_credential_provenance_predecessor_state"
                    f"[{changed_path}]=absent"
                )
            else:
                die(
                    "Engine MCP L1 credential provenance plan has no "
                    f"predecessor state: {changed_path}"
                )
            print(
                "engine_mcp_l1_credential_provenance_target_sha256"
                f"[{changed_path}]="
                f"{mcp_l1_credential_provenance_preflight['target_sha256'][changed_path]}"
            )
        print(
            "backend_current_barrier="
            f"{mcp_l1_credential_provenance_preflight['backend_mode']}"
        )
        print("backend_force_recreate=yes")
        print("backend_pull=never")
        print("l2_graph=untouched")
        print("n8n_l1=untouched")
        print("engine_ui=untouched")
        print("engine_databases=untouched")
        print("credentials=preserved")
        print("mcp_nginx=untouched")
        print("embedded_ai_workspace=untouched")
    if mcp_execution_plan_sandbox_runtime_preflight:
        print(
            "engine_mcp_execution_plan_sandbox_runtime_transition="
            f"{mcp_execution_plan_sandbox_runtime_preflight['mode']}"
        )
        print("engine_mcp_version=0.11.0")
        print("engine_mcp_execution_plan_compiler_version=1.4.0")
        print("engine_mcp_execution_runtime=n8n-2.3.2-code")
        print("engine_mcp_execution_sandbox_global_dependencies=none")
        print("engine_mcp_execution_byte_budget=pure-js-utf8")
        print("engine_mcp_provider_logic=trusted-package")
        print("engine_mcp_provider_hardcode=no")
        print("engine_mcp_raw_provider_publish=forbidden")
        for foundation_path, foundation_sha256 in (
            mcp_execution_plan_sandbox_runtime_preflight[
                "foundation_sha256"
            ].items()
        ):
            print(
                "engine_mcp_execution_plan_sandbox_runtime_foundation_sha256"
                f"[{foundation_path}]={foundation_sha256}"
            )
        for changed_path in (
            ENGINE_MCP_EXECUTION_PLAN_SANDBOX_RUNTIME_ARTIFACT_ENTRIES
        ):
            print(
                "engine_mcp_execution_plan_sandbox_runtime_changed_path="
                f"{changed_path}"
            )
            if changed_path in (
                mcp_execution_plan_sandbox_runtime_preflight[
                    "predecessor_sha256"
                ]
            ):
                print(
                    "engine_mcp_execution_plan_sandbox_runtime_predecessor_sha256"
                    f"[{changed_path}]="
                    f"{mcp_execution_plan_sandbox_runtime_preflight['predecessor_sha256'][changed_path]}"
                )
            elif changed_path in (
                mcp_execution_plan_sandbox_runtime_preflight["new_paths"]
            ):
                print(
                    "engine_mcp_execution_plan_sandbox_runtime_predecessor_state"
                    f"[{changed_path}]=absent"
                )
            else:
                die(
                    "Engine MCP execution plan sandbox runtime plan has no "
                    f"predecessor state: {changed_path}"
                )
            print(
                "engine_mcp_execution_plan_sandbox_runtime_target_sha256"
                f"[{changed_path}]="
                f"{mcp_execution_plan_sandbox_runtime_preflight['target_sha256'][changed_path]}"
            )
        print(
            "backend_current_barrier="
            f"{mcp_execution_plan_sandbox_runtime_preflight['backend_mode']}"
        )
        print("backend_force_recreate=yes")
        print("backend_pull=never")
        print("l2_graph=untouched")
        print("n8n_l1=untouched")
        print("n8n_core=untouched")
        print("engine_ui=untouched")
        print("engine_databases=untouched")
        print("credentials=preserved")
        print("mcp_nginx=untouched")
        print("embedded_ai_workspace=untouched")
    if mcp_gelios_items_envelope_preflight:
        print(
            "engine_mcp_gelios_items_envelope_transition="
            f"{mcp_gelios_items_envelope_preflight['mode']}"
        )
        print("engine_mcp_version=0.11.0")
        print("engine_mcp_provider_package=gelios.provider.v12")
        print("engine_mcp_response_collection_path=items")
        print("engine_mcp_execution_history_v11=preserved")
        print("engine_mcp_security_authority_v12=exclusive")
        print("engine_mcp_provider_logic=trusted-package")
        print("engine_mcp_compiler_changed=no")
        print("engine_mcp_raw_provider_values_included=no")
        for foundation_path, foundation_sha256 in (
            mcp_gelios_items_envelope_preflight[
                "foundation_sha256"
            ].items()
        ):
            print(
                "engine_mcp_gelios_items_envelope_foundation_sha256"
                f"[{foundation_path}]={foundation_sha256}"
            )
        for changed_path in (
            ENGINE_MCP_GELIOS_ITEMS_ENVELOPE_ARTIFACT_ENTRIES
        ):
            print(
                "engine_mcp_gelios_items_envelope_changed_path="
                f"{changed_path}"
            )
            if changed_path in (
                mcp_gelios_items_envelope_preflight["predecessor_sha256"]
            ):
                print(
                    "engine_mcp_gelios_items_envelope_predecessor_sha256"
                    f"[{changed_path}]="
                    f"{mcp_gelios_items_envelope_preflight['predecessor_sha256'][changed_path]}"
                )
            elif changed_path in (
                mcp_gelios_items_envelope_preflight["new_paths"]
            ):
                print(
                    "engine_mcp_gelios_items_envelope_predecessor_state"
                    f"[{changed_path}]=absent"
                )
            else:
                die(
                    "Engine MCP Gelios items envelope plan has no predecessor "
                    f"state: {changed_path}"
                )
            print(
                "engine_mcp_gelios_items_envelope_target_sha256"
                f"[{changed_path}]="
                f"{mcp_gelios_items_envelope_preflight['target_sha256'][changed_path]}"
            )
        print(
            "backend_current_barrier="
            f"{mcp_gelios_items_envelope_preflight['backend_mode']}"
        )
        print("backend_force_recreate=yes")
        print("backend_pull=never")
        print("l2_graph=untouched")
        print("n8n_l1=untouched")
        print("n8n_core=untouched")
        print("engine_ui=untouched")
        print("engine_databases=untouched")
        print("credentials=preserved")
        print("mcp_nginx=untouched")
        print("embedded_ai_workspace=untouched")
    if mcp_registered_execution_profiles_preflight:
        print(
            "engine_mcp_registered_execution_profiles_transition="
            f"{mcp_registered_execution_profiles_preflight['mode']}"
        )
        print("engine_mcp_version=0.12.0")
        print(
            "engine_mcp_tool=engine_list_l2_execution_profiles,"
            "engine_plan_registered_l2_execution"
        )
        print("engine_mcp_registered_profiles=6")
        print("engine_mcp_profile_refs=actor-and-target-scoped-opaque-ttl")
        print("engine_mcp_target_scope=server-derived")
        print("engine_mcp_execution_plan_digests=server-derived")
        print("engine_mcp_existing_materializer=reused")
        print("engine_mcp_provider_hardcode=no")
        print("engine_mcp_internal_descriptors_included=no")
        print("engine_mcp_provider_endpoints_included=no")
        print("engine_mcp_customer_scope_included=no")
        print("engine_mcp_credential_ids_included=no")
        print("engine_mcp_credential_values_included=no")
        print("engine_node_intelligence_attestation=updated")
        print("engine_node_intelligence_image=untouched")
        print("engine_node_intelligence_source=untouched")
        for foundation_path, foundation_sha256 in (
            mcp_registered_execution_profiles_preflight[
                "foundation_sha256"
            ].items()
        ):
            print(
                "engine_mcp_registered_execution_profiles_foundation_sha256"
                f"[{foundation_path}]={foundation_sha256}"
            )
        for changed_path in (
            ENGINE_MCP_REGISTERED_EXECUTION_PROFILES_ARTIFACT_ENTRIES
        ):
            print(
                "engine_mcp_registered_execution_profiles_changed_path="
                f"{changed_path}"
            )
            if changed_path in (
                mcp_registered_execution_profiles_preflight[
                    "predecessor_sha256"
                ]
            ):
                print(
                    "engine_mcp_registered_execution_profiles_predecessor_sha256"
                    f"[{changed_path}]="
                    f"{mcp_registered_execution_profiles_preflight['predecessor_sha256'][changed_path]}"
                )
            elif changed_path in (
                mcp_registered_execution_profiles_preflight["new_paths"]
            ):
                print(
                    "engine_mcp_registered_execution_profiles_predecessor_state"
                    f"[{changed_path}]=absent"
                )
            else:
                die(
                    "Engine MCP registered execution profiles plan has no "
                    f"predecessor state: {changed_path}"
                )
            print(
                "engine_mcp_registered_execution_profiles_target_sha256"
                f"[{changed_path}]="
                f"{mcp_registered_execution_profiles_preflight['target_sha256'][changed_path]}"
            )
        print(
            "backend_current_barrier="
            f"{mcp_registered_execution_profiles_preflight['backend_mode']}"
        )
        print("backend_force_recreate=yes")
        print("backend_pull=never")
        print("l2_graph=untouched")
        print("n8n_l1=untouched")
        print("n8n_core=untouched")
        print("engine_ui=untouched")
        print("engine_databases=untouched")
        print("credentials=preserved")
        print("foundry=untouched")
        print("ontology=untouched")
        print("mcp_nginx=untouched")
        print("embedded_ai_workspace=untouched")
    if mcp_gelios_units_items_preflight:
        print(
            "engine_mcp_gelios_units_items_transition="
            f"{mcp_gelios_units_items_preflight['mode']}"
        )
        print("engine_mcp_version=0.12.0")
        print("engine_mcp_provider_package=gelios.provider.v12@12.0.1")
        print("engine_mcp_registered_profile=gelios.units.profile.cold.v1")
        print("engine_mcp_data_product=fleet.units.profile.current.v1")
        print("engine_mcp_response_collection_path=items")
        print("engine_mcp_execution_plan_compiler_version=1.4.0")
        print("engine_mcp_existing_materializer=reused")
        print("engine_mcp_runtime_code_changed=no")
        print("engine_mcp_provider_endpoints_changed=no")
        print("engine_mcp_raw_provider_values_included=no")
        for foundation_path, foundation_sha256 in (
            mcp_gelios_units_items_preflight["foundation_sha256"].items()
        ):
            print(
                "engine_mcp_gelios_units_items_foundation_sha256"
                f"[{foundation_path}]={foundation_sha256}"
            )
        for changed_path in ENGINE_MCP_GELIOS_UNITS_ITEMS_ARTIFACT_ENTRIES:
            print(
                "engine_mcp_gelios_units_items_changed_path="
                f"{changed_path}"
            )
            if changed_path in (
                mcp_gelios_units_items_preflight["predecessor_sha256"]
            ):
                print(
                    "engine_mcp_gelios_units_items_predecessor_sha256"
                    f"[{changed_path}]="
                    f"{mcp_gelios_units_items_preflight['predecessor_sha256'][changed_path]}"
                )
            elif changed_path in mcp_gelios_units_items_preflight["new_paths"]:
                print(
                    "engine_mcp_gelios_units_items_predecessor_state"
                    f"[{changed_path}]=absent"
                )
            else:
                die(
                    "Engine MCP Gelios units items plan has no predecessor "
                    f"state: {changed_path}"
                )
            print(
                "engine_mcp_gelios_units_items_target_sha256"
                f"[{changed_path}]="
                f"{mcp_gelios_units_items_preflight['target_sha256'][changed_path]}"
            )
        print(
            "backend_current_barrier="
            f"{mcp_gelios_units_items_preflight['backend_mode']}"
        )
        print("backend_force_recreate=yes")
        print("backend_pull=never")
        print("l2_graph=untouched")
        print("n8n_l1=untouched")
        print("n8n_core=untouched")
        print("engine_ui=untouched")
        print("engine_databases=untouched")
        print("credentials=preserved")
        print("foundry=untouched")
        print("ontology=untouched")
        print("mcp_nginx=untouched")
        print("embedded_ai_workspace=untouched")
    if transition_descriptor:
        print(f"n8n_transition={transition_descriptor['action']}")
        print(f"n8n_version={transition_descriptor['n8nVersion']}")
        print(f"n8n_release={transition_descriptor['releaseId']}")
        print(f"n8n_package_sha256={transition_descriptor['packageSha256']}")
        print(f"n8n_base_image={transition_descriptor['baseImage']}")
        print(f"n8n_base_image_id={transition_preflight['base_image_id']}")
        print(f"n8n_base_image_architecture={transition_preflight['base_image_architecture']}")
        for repo_digest in transition_preflight["base_image_repo_digests"]:
            print(f"n8n_base_image_repo_digest={repo_digest}")
        print(f"n8n_current_state={transition_preflight['current_state']}")
        print(f"n8n_expected_current={transition_descriptor['expectedCurrent']}")
        print(f"n8n_state_matches={'yes' if transition_preflight['state_matches'] else 'not-yet'}")
        print(f"n8n_sealed_package=/volume2/nodedc-demo/{transition_descriptor['sealedReleaseRelativePath']}")
        print("n8n_build=none")
        print("n8n_pull=never")
        print("n8n_force_recreate=yes")
        print("n8n_persistent_data=preserved:/volume2/nodedc-demo/n8n-data")
        print("n8n_database=preserved:n8n-postgres")
        print(f"n8n_expected_node_types={','.join(transition_descriptor['expectedNodeTypes'])}")
        print(f"n8n_expected_credential_types={','.join(transition_descriptor['expectedCredentialTypes'])}")
        print(f"n8n_rollback_baseline={transition_descriptor['rollbackBaseline']}")
    touches_map_gateway = component == "platform" and any(rel == "platform/services/map-gateway" or rel.startswith("platform/services/map-gateway/") for rel in entries)
    touches_external_data_plane = component == "platform" and touches_external_data_plane_files(entries)
    if component == "module-foundry" or touches_map_gateway:
        print(f"runtime_secret=runner-managed:{MAP_GATEWAY_SECRET_FILE}")
    if component == "module-foundry":
        print(f"runtime_grants=runner-managed:{EXTERNAL_DATA_PLANE_READER_GRANTS_DIR}")
        print(f"runtime_grants=runner-managed:{FOUNDRY_BINDING_GRANTS_DIR}")
        print(f"runtime_private_key=runner-managed:{FOUNDRY_EDP_MANAGED_PROVISIONER_PRIVATE_KEY_FILE}")
        print(f"runtime_public_trust=runner-managed:{FOUNDRY_EDP_MANAGED_PROVISIONER_PUBLIC_KEY_FILE}")
    if component == "device-plane":
        print(f"runtime_secret=runner-managed:{DEVICE_PLANE_POSTGRES_PASSWORD_FILE}")
        print(f"runtime_secret=runner-managed:{DEVICE_PLANE_GATEWAY_CORE_TOKEN_FILE}")
        print(f"runtime_secret=runner-managed:{DEVICE_PLANE_IDENTIFIER_PEPPER_FILE}")
        print(
            "device_postgres="
            f"{device_plane_postgres_plan_selection(device_plane_postgres_preflight)}"
        )
        print("device_postgres_volume=preserved:nodedc-device-plane-postgres-data")
        print("device_gateway_public_ingress=disabled")
        print("device_gateway_command_transport=disabled")
        print("gelios=untouched")
        if device_plane_postgres_preflight is not None:
            print(
                "device_postgres_bootstrap="
                f"{device_plane_postgres_preflight}"
            )
            print("device_postgres_bootstrap_mode=create-if-absent")
            print("device_postgres_rollback_volume=preserve")
    if touches_external_data_plane:
        print(f"runtime_secret=runner-managed:{EXTERNAL_DATA_PLANE_PROVISIONER_SECRET_FILE}")
        print(f"runtime_grants=runner-managed:{EXTERNAL_DATA_PLANE_READER_GRANTS_DIR}")
        print(f"runtime_public_trust=runner-managed:{FOUNDRY_EDP_MANAGED_PROVISIONER_PUBLIC_KEY_FILE}")
    if touches_engine_credential_sink(component, entries):
        print(f"runtime_identity_key_id={ENGINE_CREDENTIAL_PROVISIONER_KEY_ID}")
        print(f"runtime_private_key=runner-managed:{ENGINE_CREDENTIAL_PROVISIONER_PRIVATE_KEY_FILE}")
        print(f"runtime_public_key=runner-managed:{ENGINE_CREDENTIAL_SINK_PUBLIC_KEY_FILE}")
    if touches_engine_credential_sink(component, entries):
        print(f"backend_source_container_id={credential_backend_preflight['container_id']}")
        print(f"backend_source_image_id={credential_backend_preflight['source_image_id']}")
        print(f"backend_current_image_id={credential_backend_preflight['current_image_id']}")
        print(f"backend_current_barrier={credential_backend_preflight['mode']}")
        print(f"backend_derived_image={ENGINE_CREDENTIAL_BACKEND_IMAGE}")
        print(f"backend_package_lock_sha256={ENGINE_CREDENTIAL_BACKEND_PACKAGE_LOCK_SHA256}")
        print(f"backend_node_modules_tree_sha256={credential_backend_preflight['node_modules_tree_sha256']}")
        print("backend_rootfs=safe-roots:/bin,/sbin,/lib,/usr,/etc,/var/lib/apk")
        print("backend_build_network=none")
        print("backend_pull=never")
        print("backend_force_recreate=yes")
    if touches_publish_grant or touches_external_data_plane:
        print(f"runtime_private_key=runner-managed:{ENGINE_EDP_MANAGED_PROVISIONER_PRIVATE_KEY_FILE}")
        print(f"runtime_public_trust=runner-managed:{ENGINE_EDP_MANAGED_PROVISIONER_PUBLIC_KEY_FILE}")
    if touches_publish_grant:
        print(f"publish_grant_transition={publish_grant_preflight['mode']}")
        for changed_path in publish_grant_preflight["changed_paths"]:
            print(f"publish_grant_changed_path={changed_path}")
        print(f"predecessor_compose_sha256={publish_grant_predecessor_sha256}")
        print(f"backend_current_barrier={credential_backend_preflight['mode']}")
        print(f"runtime_private_state=runner-managed:{component_root('engine') / ENGINE_PUBLISH_GRANT_STATE_REL}")
        if publish_grant_preflight["mode"] == "installed-composite-provider-update":
            print("engine_provider_package=gelios.provider.v4")
            print("engine_provider_requests=monitoring-config,units?incltrip=true")
            print("engine_data_product=fleet.positions.current.v3")
            print(
                "predecessor_catalog_sha256="
                f"{ENGINE_PUBLISH_GRANT_COMPOSITE_PROVIDER_CATALOG_PREDECESSOR_SHA256}"
            )
            print(
                "target_catalog_sha256="
                f"{ENGINE_PUBLISH_GRANT_COMPOSITE_PROVIDER_CATALOG_TARGET_SHA256}"
            )
            print("provider_credential_values=preserved")
    if touches_agent_grant_migration:
        print(f"predecessor_store_sha256={agent_grant_migration_predecessor_sha256}")
        print(f"target_store_sha256={ENGINE_AGENT_FULL_GRANT_MIGRATION_TARGET_SHA256}")
        print(f"backend_current_barrier={credential_backend_preflight['mode']}")
        print("agent_grant_migration=v1-full-bundle-to-v2-named-full-developer-profile")
        print("backend_pull=never")
    if component in ("proxy-contur", "dc-amd-proxy") or touches_map_gateway:
        print(f"runtime_secret=runner-synced:{MAP_EGRESS_PROXY_SECRET_FILE}")
    if component == "dc-amd-proxy":
        print(f"runtime_state=runner-prepared:{DC_AMD_PROXY_RUNTIME_DIR}")
    if state_has_sha(sha):
        print("state=sha-already-applied")
    elif state_has_patch_id(manifest["id"]):
        print("state=patch-id-already-applied")
    else:
        print("state=new")
    print("== files ==")
    for rel in entries:
        print(f"  {rel}")


def add_backup_path(tar, root, rel):
    src = root / rel
    if src.exists():
        tar.add(src, arcname=rel, recursive=True)
        return True
    return False


def create_backup(root, backup_dir, entries, include_nginx_html):
    existing = []
    missing = []

    with tarfile.open(backup_dir / "source-before.tgz", "w:gz") as tar:
        for rel in entries:
            if add_backup_path(tar, root, rel):
                existing.append(rel)
            else:
                missing.append(rel)

        if include_nginx_html and (root / "nginx-html").exists():
            tar.add(root / "nginx-html", arcname="nginx-html", recursive=True)
            existing.append("nginx-html")

    (backup_dir / "existing-files.txt").write_text("\n".join(existing) + ("\n" if existing else ""), encoding="utf-8")
    (backup_dir / "missing-files.txt").write_text("\n".join(missing) + ("\n" if missing else ""), encoding="utf-8")


def read_backup_path_list(path):
    if not path.is_file():
        die(f"deploy backup path list missing: {path}")
    return [line.strip() for line in path.read_text(encoding="utf-8").splitlines() if line.strip()]


def validate_backup_partition(entries, existing, missing, label):
    entry_set = set(entries)
    existing_set = set(existing)
    missing_set = set(missing)
    if len(entry_set) != len(entries):
        die(f"{label} entries contain duplicates")
    if len(existing_set) != len(existing) or len(missing_set) != len(missing):
        die(f"{label} backup path lists contain duplicates")
    if existing_set & missing_set or existing_set | missing_set != entry_set:
        die(f"{label} backup entry set mismatch")
    for rel in entries:
        if any(rel != other and rel.startswith(other.rstrip("/") + "/") for other in entries):
            die(f"{label} entries overlap")
    return existing_set, missing_set


def materialize_backup_tree(backup_archive, restore_root, existing):
    seen_names = set()
    seen_roots = set()
    directory_modes = []
    member_count = 0
    payload_bytes = 0
    with tarfile.open(backup_archive, "r:gz") as archive:
        for member in archive:
            member_count += 1
            if member_count > MAX_MEMBER_COUNT:
                die("Platform rollback backup has too many members")
            validate_posix_path(member.name)
            if member.name in seen_names:
                die("Platform rollback backup contains duplicate members")
            seen_names.add(member.name)
            owners = [
                rel
                for rel in existing
                if member.name == rel or member.name.startswith(rel.rstrip("/") + "/")
            ]
            if len(owners) != 1:
                die("Platform rollback backup contains an unexpected member")
            if member.name == owners[0]:
                seen_roots.add(owners[0])
            if not (member.isfile() or member.isdir()):
                die("Platform rollback backup contains an unsupported member")
            if member.mode & (stat.S_ISUID | stat.S_ISGID):
                die("Platform rollback backup contains a privileged member")

            target = tar_name_to_path(restore_root, member.name)
            if member.isdir():
                target.mkdir(parents=True, exist_ok=True)
                target.chmod(0o755)
                directory_modes.append((target, stat.S_IMODE(member.mode) & 0o777))
                continue

            if member.size > MAX_FILE_BYTES:
                die("Platform rollback backup member is too large")
            payload_bytes += member.size
            if payload_bytes > MAX_PAYLOAD_BYTES:
                die("Platform rollback backup is too large")
            target.parent.mkdir(parents=True, exist_ok=True)
            if target.exists():
                die("Platform rollback backup member collision")
            source = archive.extractfile(member)
            if source is None:
                die("Platform rollback backup member is unreadable")
            with source, target.open("xb") as output:
                shutil.copyfileobj(source, output, 1024 * 1024)
            target.chmod(stat.S_IMODE(member.mode) & 0o777)

    if seen_roots != set(existing):
        die("Platform rollback backup root set mismatch")
    for target, mode in sorted(directory_modes, key=lambda item: len(item[0].parts), reverse=True):
        target.chmod(mode)


def restore_platform_overlay(root, backup_dir, entries, current_stamp):
    existing = read_backup_path_list(backup_dir / "existing-files.txt")
    missing = read_backup_path_list(backup_dir / "missing-files.txt")
    existing_set, missing_set = validate_backup_partition(
        entries,
        existing,
        missing,
        "Platform rollback",
    )
    backup_archive = backup_dir / "source-before.tgz"
    try:
        backup_stat = backup_archive.lstat()
    except FileNotFoundError:
        die("Platform rollback backup archive is missing")
    if stat.S_ISLNK(backup_stat.st_mode) or not stat.S_ISREG(backup_stat.st_mode):
        die("Platform rollback backup archive is unsafe")

    with tempfile.TemporaryDirectory(prefix="platform-rollback-", dir=TMP_DIR) as tmp:
        restore_root = Path(tmp)
        materialize_backup_tree(backup_archive, restore_root, existing_set)
        for rel in entries:
            destination = root / rel
            destination_resolved = destination.resolve(strict=False)
            if not is_relative_to(destination_resolved, root.resolve()):
                die("Platform rollback target escaped component root")
            if destination.is_symlink():
                die("Platform rollback target is a symlink")

            if rel in existing_set:
                staged = restore_root / rel
                rollback_stamp = f"{current_stamp}-platform-rollback"
                if staged.is_dir():
                    replace_directory(staged, destination, rollback_stamp)
                elif staged.is_file():
                    replace_file(staged, destination, rollback_stamp)
                else:
                    die("Platform rollback staged path is missing")
                continue

            if rel not in missing_set or not destination.exists():
                continue
            if destination.is_dir():
                shutil.rmtree(destination)
            elif destination.is_file():
                destination.unlink()
            else:
                die("Platform rollback target has unsupported type")
    return len(entries)


def rollback_platform_apply(root, backup_dir, entries, current_stamp, runtime_started, applied_services):
    existing = read_backup_path_list(backup_dir / "existing-files.txt")
    missing = read_backup_path_list(backup_dir / "missing-files.txt")
    existing_set, missing_set = validate_backup_partition(
        entries,
        existing,
        missing,
        "Platform runtime rollback",
    )

    edp_was_new = PLATFORM_EXTERNAL_DATA_PLANE_COMPOSE_REL in missing_set
    candidate_cleanup_failed = False
    if runtime_started and edp_was_new:
        # Remove only candidate-only containers while its Compose overlay is
        # still installed. Deliberately omit --volumes: rollback never deletes
        # newly written data, even when the first EDP activation is rejected.
        try:
            candidate_services = tuple(
                service
                for service in applied_services
                if service == EXTERNAL_DATA_PLANE_SERVICE
            )
            if not candidate_services:
                die("Platform candidate-only EDP runtime selection is invalid")
            stop_and_remove_compose_services(
                "platform",
                candidate_services,
            )
        except Exception:
            candidate_cleanup_failed = True

    restored_count = restore_platform_overlay(root, backup_dir, entries, current_stamp)
    if candidate_cleanup_failed:
        die("Platform candidate-only runtime cleanup failed after source restore")
    if not runtime_started:
        return f"source-restored-runtime-unchanged:{restored_count}"

    baseline_entries = [rel for rel in entries if rel in existing_set]
    if edp_was_new:
        baseline_entries = [
            rel
            for rel in baseline_entries
            if not touches_external_data_plane_files((rel,))
        ]
    baseline_services = tuple(
        service
        for service in applied_services
        if not edp_was_new
        or service not in (EXTERNAL_DATA_PLANE_SERVICE, EXTERNAL_DATA_PLANE_DATABASE_SERVICE)
    )
    if baseline_services:
        run_component_runtime("platform", baseline_entries, baseline_services)
        if baseline_services == (EXTERNAL_DATA_PLANE_SERVICE,):
            # The restored EDP may predate managed provisioning. Prove the
            # stable baseline contract without requiring a candidate-only field.
            healthcheck_url(external_data_plane_healthcheck(require_managed=False))
        else:
            run_healthchecks("platform", baseline_entries, baseline_services)
    return f"source+runtime-restored:{restored_count}"


def rollback_device_plane_apply(
    root,
    backup_dir,
    entries,
    current_stamp,
    runtime_started,
    applied_services,
):
    existing = read_backup_path_list(backup_dir / "existing-files.txt")
    missing = read_backup_path_list(backup_dir / "missing-files.txt")
    existing_set, _missing_set = validate_backup_partition(
        entries,
        existing,
        missing,
        "Device Plane runtime rollback",
    )
    baseline_entries = [rel for rel in entries if rel in existing_set]
    compose_was_installed = "docker-compose.device-plane.yml" in existing_set
    baseline_services = (
        component_services("device-plane", baseline_entries)
        if compose_was_installed
        else ()
    )
    candidate_only_services = tuple(
        service
        for service in applied_services
        if service not in baseline_services
    )
    candidate_cleanup_failed = False
    if runtime_started and candidate_only_services:
        # Remove only candidate services while the candidate Compose file is
        # still present. PostgreSQL can appear only in the exact one-time
        # bootstrap slice; volume flags are deliberately never used.
        try:
            stop_and_remove_compose_services(
                "device-plane",
                candidate_only_services,
            )
        except Exception:
            candidate_cleanup_failed = True

    restored_count = restore_platform_overlay(
        root,
        backup_dir,
        entries,
        current_stamp,
    )
    if candidate_cleanup_failed:
        die("Device Plane candidate-only runtime cleanup failed after source restore")
    if not runtime_started or not baseline_services:
        return f"source-restored-runtime-unchanged:{restored_count}"

    run_component_runtime(
        "device-plane",
        baseline_entries,
        baseline_services,
    )
    run_healthchecks(
        "device-plane",
        baseline_entries,
        baseline_services,
    )
    return f"source+runtime-restored:{restored_count}"


def rollback_engine_apply(root, backup_dir, entries, current_stamp, runtime_started, applied_services):
    existing = read_backup_path_list(backup_dir / "existing-files.txt")
    missing = read_backup_path_list(backup_dir / "missing-files.txt")
    restore_entries = list(entries)
    if "nginx-html" in existing:
        restore_entries.append("nginx-html")
    validate_backup_partition(
        restore_entries,
        existing,
        missing,
        "Engine runtime rollback",
    )
    restored_count = restore_platform_overlay(
        root,
        backup_dir,
        restore_entries,
        current_stamp,
    )
    if not runtime_started:
        return f"source-restored-runtime-unchanged:{restored_count}"
    run_component_runtime("engine", entries, applied_services)
    run_healthchecks("engine", entries, applied_services)
    return f"source+runtime-restored:{restored_count}"


def validate_engine_l2_closed_loop_stable_source(root):
    stable_entries = tuple(ENGINE_L2_CLOSED_LOOP_STABLE_SHA256)
    actual = collect_exact_files(
        root,
        stable_entries,
        "Engine L2 closed-loop stable rollback",
    )
    if actual != ENGINE_L2_CLOSED_LOOP_STABLE_SHA256:
        changed = sorted(
            rel
            for rel in ENGINE_L2_CLOSED_LOOP_STABLE_SHA256
            if actual.get(rel) != ENGINE_L2_CLOSED_LOOP_STABLE_SHA256[rel]
        )
        detail = changed[0] if changed else "unknown"
        die(f"Engine L2 closed-loop stable rollback drift detected: {detail}")
    graph_repository = root / "nodedc-source/server/l2/graphRepository.js"
    if graph_repository.exists() or graph_repository.is_symlink():
        die("Engine L2 closed-loop stable rollback retained candidate-only repository")

    nginx_actual = collect_exact_files(
        root,
        ("nginx-html/index.html", "nginx-html/assets"),
        "Engine L2 closed-loop stable nginx rollback",
    )
    nginx_expected = {
        rel.replace("nodedc-source/dist/", "nginx-html/", 1): digest
        for rel, digest in ENGINE_L2_CLOSED_LOOP_STABLE_SHA256.items()
        if rel.startswith("nodedc-source/dist/")
    }
    if nginx_actual != nginx_expected:
        die("Engine L2 closed-loop stable nginx rollback drift detected")

    descriptor = current_engine_node_intelligence_descriptor()
    if descriptor is None or descriptor.get("action") != "activate":
        die("Engine L2 closed-loop stable descriptor was not restored")
    validate_installed_engine_node_intelligence_source(descriptor)
    return descriptor


def rollback_engine_l2_closed_loop_reconciliation(
    root,
    candidate_backup_dir,
    entries,
    current_stamp,
    runtime_started,
    applied_services,
):
    if tuple(entries) != ENGINE_L2_CLOSED_LOOP_ARTIFACT_ENTRIES:
        die("Engine L2 closed-loop rollback entry set mismatch")
    if tuple(applied_services) != ("nodedc-backend", "app"):
        die("Engine L2 closed-loop rollback service set mismatch")

    recovery_backup = validate_engine_l2_closed_loop_recovery_evidence()
    candidate_restore_entries = [*entries, "nginx-html"]
    validate_backup_partition(
        candidate_restore_entries,
        read_backup_path_list(candidate_backup_dir / "existing-files.txt"),
        read_backup_path_list(candidate_backup_dir / "missing-files.txt"),
        "Engine L2 closed-loop candidate rollback",
    )
    candidate_restored = restore_platform_overlay(
        root,
        candidate_backup_dir,
        candidate_restore_entries,
        f"{current_stamp}-l2-candidate",
    )

    original_entries = [
        rel
        for rel in ENGINE_L2_CLOSED_LOOP_ARTIFACT_ENTRIES
        if rel != ENGINE_L2_CLOSED_LOOP_DESCRIPTOR_REL
    ]
    original_restore_entries = [*original_entries, "nginx-html"]
    validate_backup_partition(
        original_restore_entries,
        read_backup_path_list(recovery_backup / "existing-files.txt"),
        read_backup_path_list(recovery_backup / "missing-files.txt"),
        "Engine L2 closed-loop original rollback",
    )
    original_restored = restore_platform_overlay(
        root,
        recovery_backup,
        original_restore_entries,
        f"{current_stamp}-l2-original",
    )
    validate_engine_l2_closed_loop_stable_source(root)

    total_restored = candidate_restored + original_restored
    if not runtime_started:
        return f"stable-source-restored-runtime-unchanged:{total_restored}"

    stable_entries = tuple(ENGINE_L2_CLOSED_LOOP_STABLE_SHA256)
    run_component_runtime(
        "engine",
        stable_entries,
        applied_services,
    )
    for service in applied_services:
        healthcheck_compose_service("engine", service)
    for check in component_healthchecks(
        "engine",
        stable_entries,
        applied_services,
    ):
        healthcheck_url(check)
    backend = preflight_engine_credential_backend_runtime()
    if backend["mode"] != "verified-derived-retry":
        die("Engine L2 closed-loop stable backend rollback acceptance failed")
    return f"stable-source+runtime-restored:{total_restored}"


def inactive_engine_n8n_descriptor(descriptor):
    inactive = dict(descriptor)
    inactive["action"] = "rollback-inactive"
    inactive["expectedCurrent"] = descriptor["releaseId"]
    inactive["expectedNodeTypes"] = []
    inactive["expectedCredentialTypes"] = []
    return inactive


def restore_engine_n8n_transition(root, backup_dir, entries, descriptor, current_stamp):
    existing = set(read_backup_path_list(backup_dir / "existing-files.txt"))
    missing = set(read_backup_path_list(backup_dir / "missing-files.txt"))
    if existing | missing != set(entries):
        die("Engine n8n rollback backup entry set mismatch")
    required_baseline = {
        ENGINE_N8N_NODES_CATALOG_REL,
        ENGINE_N8N_CREDENTIALS_CATALOG_REL,
        ENGINE_N8N_SCHEMA_META_REL,
    }
    if not required_baseline.issubset(existing):
        die("Engine n8n rollback baseline catalogs were not present before apply")

    with tempfile.TemporaryDirectory(prefix="engine-n8n-rollback-", dir=TMP_DIR) as tmp:
        restore_root = Path(tmp)
        with tarfile.open(backup_dir / "source-before.tgz", "r:gz") as archive:
            for rel in entries:
                if rel not in existing:
                    continue
                try:
                    member = archive.getmember(rel)
                except KeyError:
                    die(f"Engine n8n rollback backup member missing: {rel}")
                if not member.isfile():
                    die(f"Engine n8n rollback backup member is not a file: {rel}")
                source = archive.extractfile(member)
                if source is None:
                    die(f"Engine n8n rollback backup member unreadable: {rel}")
                staged = restore_root / rel
                staged.parent.mkdir(parents=True, exist_ok=True)
                with staged.open("xb") as output:
                    shutil.copyfileobj(source, output)
                replace_file(staged, root / rel, f"{current_stamp}-rollback")

    if ENGINE_N8N_TRANSITION_DESCRIPTOR_REL not in existing:
        inactive = inactive_engine_n8n_descriptor(descriptor)
        descriptor_path = root / ENGINE_N8N_TRANSITION_DESCRIPTOR_REL
        descriptor_path.parent.mkdir(parents=True, exist_ok=True)
        next_path = descriptor_path.with_name(f"{descriptor_path.name}.next-{current_stamp}-rollback")
        if next_path.exists() or next_path.is_symlink():
            die(f"Engine n8n rollback descriptor staging path exists: {next_path}")
        next_path.write_text(json.dumps(inactive, indent=2) + "\n", encoding="utf-8")
        os.replace(next_path, descriptor_path)

    restored_descriptor = current_engine_n8n_transition_descriptor()
    if restored_descriptor is None:
        die("Engine n8n rollback did not restore an explicit baseline descriptor")
    run_compose("engine", ("n8n",), entries)
    accept_engine_n8n_runtime(restored_descriptor)
    return restored_descriptor["action"]


def replace_file(src, dst, current_stamp):
    dst.parent.mkdir(parents=True, exist_ok=True)
    tmp = dst.with_name(f"{dst.name}.next-{current_stamp}")
    if tmp.exists():
        die(f"staging path already exists: {tmp}")
    shutil.copy2(src, tmp)
    os.replace(tmp, dst)


def replace_directory(src, dst, current_stamp):
    dst.parent.mkdir(parents=True, exist_ok=True)
    next_path = dst.with_name(f"{dst.name}.next-{current_stamp}")
    prev_path = dst.with_name(f"{dst.name}.prev-{current_stamp}")
    if next_path.exists() or prev_path.exists():
        die(f"staging path already exists near: {dst}")
    shutil.copytree(src, next_path)
    if dst.exists():
        dst.rename(prev_path)
    next_path.rename(dst)


def copy_payload_path(payload_dir, root, rel, current_stamp):
    src = payload_dir / rel
    dst = root / rel
    root_real = root.resolve()
    dst_real = dst.resolve(strict=False)
    if not is_relative_to(dst_real, root_real):
        die(f"target escaped component root: {rel}")

    if src.is_dir():
        replace_directory(src, dst, current_stamp)
    elif src.is_file():
        replace_file(src, dst, current_stamp)
    else:
        die(f"payload path is neither file nor directory: {rel}")


def restore_overlay_source(root, backup_dir, entries, current_stamp):
    existing = set(read_backup_path_list(backup_dir / "existing-files.txt"))
    missing = set(read_backup_path_list(backup_dir / "missing-files.txt"))
    if existing | missing != set(entries) or existing & missing:
        die("credential bridge rollback backup entry set mismatch")

    with tempfile.TemporaryDirectory(prefix="credential-bridge-rollback-", dir=TMP_DIR) as tmp:
        restore_root = Path(tmp)
        names = set()
        with tarfile.open(backup_dir / "source-before.tgz", "r:gz") as archive:
            for member in archive:
                validate_posix_path(member.name)
                if member.name in names:
                    die(f"credential bridge rollback duplicate backup member: {member.name}")
                names.add(member.name)
                if not path_is_covered_by_files_list(member.name, existing):
                    die(f"credential bridge rollback unexpected backup member: {member.name}")
                if not (member.isfile() or member.isdir()):
                    die(f"credential bridge rollback special backup member: {member.name}")
                target = tar_name_to_path(restore_root, member.name)
                if member.isdir():
                    target.mkdir(parents=True, exist_ok=True)
                    target.chmod(0o755)
                    continue
                if member.size > MAX_FILE_BYTES:
                    die(f"credential bridge rollback backup member too large: {member.name}")
                target.parent.mkdir(parents=True, exist_ok=True)
                source = archive.extractfile(member)
                if source is None:
                    die(f"credential bridge rollback unreadable backup member: {member.name}")
                with source, target.open("xb") as output:
                    shutil.copyfileobj(source, output, 1024 * 1024)
                target.chmod(0o644)

        for rel in entries:
            destination = root / rel
            if rel in existing:
                source = restore_root / rel
                if not source.exists() or source.is_symlink():
                    die(f"credential bridge rollback source missing or unsafe: {rel}")
                copy_payload_path(restore_root, root, rel, f"{current_stamp}-rollback")
                continue
            if not destination.exists() and not destination.is_symlink():
                continue
            if destination.is_symlink():
                die(f"credential bridge rollback installed symlink rejected: {rel}")
            retained = destination.with_name(f"{destination.name}.failed-{current_stamp}")
            if retained.exists() or retained.is_symlink():
                die(f"credential bridge rollback retained path already exists: {retained}")
            destination.rename(retained)


def rollback_engine_credential_bridge(
    component,
    root,
    backup_dir,
    entries,
    current_stamp,
    engine_backend_recreated=False,
    engine_backend_initial_mode=None,
):
    if not touches_engine_credential_sink(component, entries):
        die("credential bridge rollback called for unrelated artifact")
    restore_overlay_source(root, backup_dir, entries, current_stamp)
    if not engine_backend_recreated:
        if engine_backend_initial_mode == "verified-derived-retry":
            validate_engine_backend_activation_marker()
            if not engine_backend_immutable_runtime_is_current():
                raise ReconciliationRequired("engine_backend_prior_derived_runtime_unproven")
            return "engine-sink-source-restored-active-runtime-preserved"
        if engine_backend_initial_mode == "verified-prepared-not-active":
            validate_engine_backend_activation_marker()
            return "engine-sink-source-restored-prepared-runtime-preserved"
        quarantine = quarantine_engine_backend_partial_runtime()
        return f"engine-sink-source-restored-before-backend-recreate-{quarantine}"
    rollback_entries = ("nodedc-source/server/index.js",)
    # The first Compose call may have failed before replacing the base
    # container. Original sink entries explicitly authorize the already proven
    # prepared override for this rollback recreate.
    run_compose("engine", ("nodedc-backend",), entries)
    healthcheck_compose_service("engine", "nodedc-backend")
    run_healthchecks("engine", rollback_entries)
    runtime = preflight_engine_credential_backend_runtime()
    if runtime["mode"] != "verified-derived-retry":
        die("Engine backend immutable rollback runtime acceptance failed")
    return "engine-sink-source-restored"


def rollback_engine_node_intelligence(
    root,
    backup_dir,
    entries,
    current_stamp,
    runtime_started=False,
    node_intelligence_service_stopped=False,
):
    candidate_descriptor = current_engine_node_intelligence_descriptor()
    candidate_active = (
        candidate_descriptor is not None
        and candidate_descriptor["action"] == "activate"
    )
    cleanup_failed = False
    if runtime_started and candidate_active:
        try:
            stop_and_remove_compose_services(
                "engine",
                (ENGINE_NODE_INTELLIGENCE_SERVICE,),
            )
        except Exception:
            cleanup_failed = True

    restore_overlay_source(root, backup_dir, entries, current_stamp)
    restored = current_engine_node_intelligence_descriptor()
    restored_action = restored["action"] if restored is not None else "inactive"
    if cleanup_failed:
        die("Engine node-intelligence candidate runtime cleanup failed after source restore")

    reconcile_runtime = runtime_started or node_intelligence_service_stopped
    if not reconcile_runtime:
        return f"source-restored-runtime-unchanged:{restored_action}"

    if restored is not None and restored["action"] == "activate":
        validate_installed_engine_node_intelligence_source(restored)
        ensure_engine_node_intelligence_secret()
        install_engine_node_intelligence_image(restored)
        run_engine_node_intelligence_compose(
            (ENGINE_NODE_INTELLIGENCE_SERVICE, "nodedc-backend"),
            ENGINE_NODE_INTELLIGENCE_ARTIFACT_ENTRIES,
        )
        accept_engine_node_intelligence_runtime(restored)
        return "active"

    run_engine_node_intelligence_compose(
        ("nodedc-backend",),
        ENGINE_NODE_INTELLIGENCE_ROLLBACK_ENTRIES,
    )
    healthcheck_compose_service("engine", "nodedc-backend")
    healthcheck_url("http://127.0.0.1:3001/health")
    backend = preflight_engine_credential_backend_runtime()
    if backend["mode"] != "verified-derived-retry":
        die("Engine node-intelligence rollback backend barrier failed")
    assert_engine_node_intelligence_container_absent()
    return restored_action


def seal_n8n_private_extension_release(root, rel):
    release_dir = root / rel
    if not release_dir.is_dir() or release_dir.is_symlink():
        die("private extension release was not installed as a directory")
    for path in [release_dir, *release_dir.rglob("*")]:
        path_stat = path.lstat()
        if stat.S_ISLNK(path_stat.st_mode):
            die(f"private extension installed symlink rejected: {path}")
        os.chown(path, 0, 0)
        if stat.S_ISDIR(path_stat.st_mode):
            path.chmod(0o555)
        elif stat.S_ISREG(path_stat.st_mode):
            path.chmod(0o444)
        else:
            die(f"private extension installed special file rejected: {path}")


def publish_engine_dist(root, current_stamp):
    dist = root / "nodedc-source" / "dist"
    if not dist.is_dir():
        return

    dst = root / "nginx-html"
    next_path = root / f"nginx-html.next-{current_stamp}"
    prev_path = root / f"nginx-html.prev-{current_stamp}"
    if next_path.exists() or prev_path.exists():
        die("nginx-html staging path already exists")

    shutil.copytree(dist, next_path)
    if dst.exists():
        dst.rename(prev_path)
    next_path.rename(dst)


def component_publish_dist(component, entries=None):
    if not COMPONENTS[component].get("publish_dist"):
        return False
    if component == "engine":
        return entries is not None and any(
            rel == "nodedc-source/dist" or rel.startswith("nodedc-source/dist/")
            for rel in entries
        )
    return True


def run_build(component, entries=None):
    for build_root, build_args in component_builds(component, entries):
        dockerfile = "Dockerfile"
        for idx, arg in enumerate(build_args):
            if arg == "-f" and idx + 1 < len(build_args):
                dockerfile = build_args[idx + 1]
                break

        if not (build_root / dockerfile).is_file():
            die(f"Dockerfile not found in build root: {build_root / dockerfile}")

        cmd = [str(DOCKER), *build_args]
        env = os.environ.copy()
        if component == "tasker":
            env["DOCKER_BUILDKIT"] = "0"
        subprocess.run(cmd, cwd=str(build_root), env=env, check=True)


def compose_base_cmd(
    component,
    allow_prepared_engine_backend=False,
    expected_node_intelligence_gateway_sha256=None,
):
    cmd = [str(DOCKER), "compose"]
    compose_project = component_compose_project(component)
    if compose_project:
        cmd.extend(["-p", compose_project])
    env_file = component_compose_env_file(component)
    if env_file:
        cmd.extend(["--env-file", str(env_file)])
    for compose_file in component_compose_files(
        component,
        allow_prepared_engine_backend=allow_prepared_engine_backend,
        expected_node_intelligence_gateway_sha256=
            expected_node_intelligence_gateway_sha256,
    ):
        cmd.extend(["-f", str(compose_file)])
    return cmd


def run_compose(component, services, entries=None):
    compose_root = component_compose_root(component)
    allow_prepared_engine_backend = touches_engine_credential_sink(component, entries)
    cmd = [
        *compose_base_cmd(
            component,
            allow_prepared_engine_backend=allow_prepared_engine_backend,
        ),
        "up", "-d", "--force-recreate",
    ]
    if (is_engine_n8n_transition(component, entries)
            or touches_engine_credential_sink(component, entries)
            or touches_engine_credential_provisioner(component, entries)
            or (component == "engine" and ENGINE_CREDENTIAL_BACKEND_ACTIVATION_FILE.exists())):
        cmd.extend(["--pull", "never"])
    if COMPONENTS[component].get("compose_build"):
        cmd.append("--build")
    if component_compose_no_deps(component, entries):
        cmd.append("--no-deps")
    cmd.extend(services)
    try:
        subprocess.run(cmd, cwd=str(compose_root), check=True)
    except subprocess.CalledProcessError:
        subprocess.run(
            [
                *compose_base_cmd(
                    component,
                    allow_prepared_engine_backend=allow_prepared_engine_backend,
                ),
                "logs", "--no-color", "--tail=180", *services,
            ],
            cwd=str(compose_root),
            check=False,
        )
        raise
    subprocess.run(
        [
            *compose_base_cmd(
                component,
                allow_prepared_engine_backend=allow_prepared_engine_backend,
            ),
            "ps",
        ],
        cwd=str(compose_root),
        check=True,
    )


def run_engine_node_intelligence_compose(services, entries):
    if not is_engine_node_intelligence_transition("engine", entries):
        die("Engine node-intelligence Compose called for unrelated artifact")
    compose_root = component_compose_root("engine")
    cmd = [
        *compose_base_cmd("engine"),
        "up",
        "-d",
        "--force-recreate",
        "--pull",
        "never",
        "--no-deps",
        *services,
    ]
    try:
        subprocess.run(cmd, cwd=str(compose_root), check=True)
    except subprocess.CalledProcessError:
        subprocess.run(
            [
                *compose_base_cmd("engine"),
                "logs",
                "--no-color",
                "--tail=180",
                *services,
            ],
            cwd=str(compose_root),
            check=False,
        )
        raise
    subprocess.run(
        [*compose_base_cmd("engine"), "ps"],
        cwd=str(compose_root),
        check=True,
    )


def stop_and_remove_compose_services(component, services):
    if not services:
        return
    compose_root = component_compose_root(component)
    subprocess.run(
        [*compose_base_cmd(component), "rm", "--stop", "--force", *services],
        cwd=str(compose_root),
        check=True,
    )


def prepare_component_runtime(component, entries=None):
    if is_engine_data_product_publish_grant_slice(component, entries):
        ensure_engine_edp_managed_provisioner_keypair()
        ensure_engine_publish_grant_private_state()

    if is_engine_mcp_control_plane_slice(component, entries):
        ensure_engine_edp_managed_provisioner_keypair()
        ensure_engine_data_product_grant_private_state(include_reader=True)

    if is_engine_n8n_transition(component, entries):
        descriptor = current_engine_n8n_transition_descriptor()
        if descriptor is None:
            die("installed Engine n8n transition descriptor is missing")
        if descriptor["action"] == "activate":
            ensure_engine_n8n_sealed_release(descriptor, stamp())
        return

    if is_engine_node_intelligence_transition(component, entries):
        ensure_engine_node_intelligence_secret()
        descriptor = current_engine_node_intelligence_descriptor()
        if descriptor is None:
            die("installed Engine node-intelligence descriptor is missing")
        if descriptor["action"] == "activate":
            install_engine_node_intelligence_image(descriptor)
        return

    if touches_engine_credential_sink(component, entries):
        ensure_engine_credential_issuer_keypair()
        prepare_engine_credential_backend_runtime()
        return

    if component == "module-foundry":
        ensure_map_gateway_admin_secret()
        ensure_foundry_edp_managed_provisioner_keypair()
        ensure_root_owned_grant_directory(
            EXTERNAL_DATA_PLANE_READER_GRANTS_DIR,
            "external data plane reader grants",
        )
        ensure_root_owned_grant_directory(
            FOUNDRY_BINDING_GRANTS_DIR,
            "foundry binding grants",
        )
        return

    if component == "device-plane":
        ensure_platform_runtime_secret(
            DEVICE_PLANE_POSTGRES_PASSWORD_FILE,
            MAP_GATEWAY_SECRET_RE,
            "device plane PostgreSQL",
        )
        ensure_platform_runtime_secret(
            DEVICE_PLANE_GATEWAY_CORE_TOKEN_FILE,
            MAP_GATEWAY_SECRET_RE,
            "device plane Gateway to Core",
        )
        ensure_platform_runtime_secret(
            DEVICE_PLANE_IDENTIFIER_PEPPER_FILE,
            MAP_GATEWAY_SECRET_RE,
            "device plane identifier pepper",
        )
        return

    if component == "proxy-contur":
        sync_map_egress_proxy_secret()
        return

    if component == "dc-amd-proxy":
        # The connector access value arrives only through the one-time pairing
        # endpoint. The artifact must never carry it, and the service user is
        # the only non-root identity that can write this directory.
        sync_map_egress_proxy_secret()
        try:
            runtime_stat = DC_AMD_PROXY_RUNTIME_DIR.lstat()
        except FileNotFoundError:
            DC_AMD_PROXY_RUNTIME_DIR.mkdir(parents=True, exist_ok=False)
            runtime_stat = DC_AMD_PROXY_RUNTIME_DIR.lstat()
        if stat.S_ISLNK(runtime_stat.st_mode) or not stat.S_ISDIR(runtime_stat.st_mode):
            die(f"dc-amd-proxy runtime directory is unsafe: {DC_AMD_PROXY_RUNTIME_DIR}")
        os.chown(DC_AMD_PROXY_RUNTIME_DIR, MAP_GATEWAY_RUNTIME_GID, MAP_GATEWAY_RUNTIME_GID)
        DC_AMD_PROXY_RUNTIME_DIR.chmod(0o700)

        connector_state = DC_AMD_PROXY_RUNTIME_DIR / "connector-access"
        if connector_state.exists() or connector_state.is_symlink():
            connector_stat = connector_state.lstat()
            if (
                stat.S_ISLNK(connector_stat.st_mode)
                or not stat.S_ISREG(connector_stat.st_mode)
                or connector_stat.st_uid != MAP_GATEWAY_RUNTIME_GID
                or connector_stat.st_mode & (stat.S_IRWXG | stat.S_IRWXO)
                or connector_stat.st_size > 512
            ):
                die("dc-amd-proxy connector pair state is unsafe")
        return

    if component == "platform" and entries is not None:
        touches_map_gateway = any(rel == "platform/services/map-gateway" or rel.startswith("platform/services/map-gateway/") for rel in entries)
        touches_external_data_plane = touches_external_data_plane_files(entries)
        if touches_map_gateway:
            # These NAS directories are the only canonical persistent stores
            # for all Map Page instances. Creation lives in the root-owned
            # runner, never in a user-supplied artifact or a Compose side effect.
            cache_root = Path("/volume1/docker/nodedc-platform/map-gateway")
            for cache_dir in (cache_root / "live-tile-cache", cache_root / "offline-snapshot"):
                cache_dir.mkdir(parents=True, exist_ok=True)
                os.chown(cache_dir, 1000, 1000)
                os.chmod(cache_dir, 0o750)
            ensure_map_gateway_admin_secret()
            sync_map_egress_proxy_secret()
        if touches_external_data_plane:
            ensure_external_data_plane_provisioner_secret()
            ensure_engine_edp_managed_provisioner_keypair()
            ensure_foundry_edp_managed_provisioner_keypair()
            ensure_root_owned_grant_directory(
                EXTERNAL_DATA_PLANE_READER_GRANTS_DIR,
                "external data plane reader grants",
            )
        return

    if component in ("dc-cms", "dc-cms-site-nodedc"):
        (Path("/volume1/docker/dc-cms/sites") / "nodedc").mkdir(parents=True, exist_ok=True)
        return

    if component != "bim-viewer":
        return

    data_root = component_root(component) / "server" / "data"
    for rel in ("uploads", "projects", "shares", "models", "comments"):
        (data_root / rel).mkdir(parents=True, exist_ok=True)


def run_component_runtime(component, entries, services):
    if component == "platform" and is_platform_provider_catalog_only(entries):
        return
    if component_artifact_only(component):
        return
    run_build(component, entries)
    prepare_component_runtime(component, entries)
    if is_engine_node_intelligence_transition(component, entries):
        run_engine_node_intelligence_compose(services, entries)
    else:
        run_compose(component, services, entries)


def healthcheck_url(check):
    headers = {}
    expected_json = {}
    if isinstance(check, dict):
        url = check.get("url")
        headers = check.get("headers") or {}
        expected_json = check.get("expected_json") or {}
    else:
        url = check

    last_error = None
    for _attempt in range(1, 61):
        try:
            request = urllib.request.Request(url, headers=headers)
            with NO_REDIRECT_OPENER.open(request, timeout=10) as response:
                if 200 <= response.status < 400:
                    if expected_json:
                        raw = response.read(64 * 1024 + 1)
                        if len(raw) > 64 * 1024:
                            last_error = "health response too large"
                            continue
                        try:
                            payload = json.loads(raw.decode("utf-8"))
                        except (UnicodeDecodeError, json.JSONDecodeError):
                            last_error = "health response is not json"
                            continue
                        if not isinstance(payload, dict) or any(
                            payload.get(key) != expected
                            for key, expected in expected_json.items()
                        ):
                            last_error = "health response contract mismatch"
                            continue
                    return
                last_error = f"HTTP {response.status}"
        except urllib.error.HTTPError as exc:
            if 200 <= exc.code < 400 and not expected_json:
                return
            last_error = f"HTTP {exc.code}"
        except Exception as exc:
            last_error = str(exc)
        time.sleep(5)
    die(f"healthcheck failed for {url}: {last_error}")


def external_data_plane_healthcheck(require_managed=True):
    expected_json = {
        "ok": True,
        "service": "nodedc-external-data-plane",
        "database": "ready",
    }
    if require_managed:
        expected_json["managedWriterBindingProvisioning"] = "enabled"
        server_source = (
            component_root("platform")
            / "platform/services/external-data-plane/src/server.mjs"
        )
        try:
            server_text = server_source.read_text(encoding="utf-8")
        except (OSError, UnicodeDecodeError):
            server_text = ""
        if 'managedReaderBindingProvisioning: config.managedProvisionerApiEnabled' in server_text:
            expected_json["managedReaderBindingProvisioning"] = "enabled"
        if 'managedWriterBindingLifetime: config.managedProvisionerApiEnabled ? "explicit-revoke" : "disabled"' in server_text:
            expected_json["managedWriterBindingLifetime"] = "explicit-revoke"
        if 'managedReaderBindingLifetime: config.managedProvisionerApiEnabled ? "explicit-revoke" : "disabled"' in server_text:
            expected_json["managedReaderBindingLifetime"] = "explicit-revoke"
        if 'foundryReaderBindingProvisioning: config.foundryProvisionerApiEnabled ? "digest+server-resolved-source" : "disabled"' in server_text:
            expected_json["foundryReaderBindingProvisioning"] = "digest+server-resolved-source"
            expected_json["foundryReaderBindingLifetime"] = "explicit-revoke"
    return {
        "url": "http://127.0.0.1:18106/healthz",
        "expected_json": expected_json,
    }


def module_foundry_healthcheck():
    expected_json = {
        "status": "ok",
        "service": "nodedc-module-foundry",
    }
    server_source = component_root("module-foundry") / "server/catalog-server.mjs"
    try:
        server_text = server_source.read_text(encoding="utf-8")
    except (OSError, UnicodeDecodeError):
        server_text = ""
    if "dataProductConsumerProvisioner" in server_text:
        expected_json["dataProductConsumerProvisioner"] = {
            "configured": True,
            "auth": "dedicated-ed25519-service-identity",
            "sourceScope": "external-data-plane-resolved",
        }
    return {
        "url": "http://172.22.0.222:9920/healthz",
        "expected_json": expected_json,
    }


def component_healthchecks(component, entries=None, services=None):
    if is_device_plane_postgres_bootstrap_slice(component, entries):
        return ()
    if is_engine_n8n_transition(component, entries):
        # The transition does not restart the Engine UI/backend generation.
        # Its own acceptance below verifies n8n readiness, image, mount, logs,
        # live node export and the pinned Engine MCP catalogs.
        return ()
    if is_engine_node_intelligence_transition(component, entries):
        # The exact sidecar/backend topology and live MCP capability calls are
        # accepted separately below. Keep the generic HTTP barrier scoped to
        # the backend generation recreated by this transition.
        return ("http://127.0.0.1:3001/health",)
    if component == "platform" and entries is not None and is_platform_provider_catalog_only(entries):
        return ()
    if component == "module-foundry":
        return (module_foundry_healthcheck(),)
    if component == "device-plane":
        selected_services = (
            tuple(services)
            if services is not None
            else component_services(component, entries)
        )
        checks = []
        if "device-control-core" in selected_services:
            checks.append({
                "url": "http://127.0.0.1:18120/healthz",
                "expected_json": {
                    "ok": True,
                    "service": "nodedc-device-control-core",
                    "database": "ready",
                    "discoveryIngest": "disabled",
                    "commandTransport": "disabled",
                },
            })
        if "device-gateway" in selected_services:
            checks.append({
                "url": "http://127.0.0.1:18121/healthz",
                "expected_json": {
                    "ok": True,
                    "service": "nodedc-device-gateway",
                    "tcpListener": "disabled",
                    "publicIngress": "disabled",
                    "commandTransport": "disabled",
                },
            })
        return tuple(checks)
    if (
        (
            is_engine_data_product_publish_grant_slice(component, entries)
            or is_engine_composite_provider_v4_slice(component, entries)
            or is_engine_provider_rotating_slot_slice(component, entries)
            or is_engine_provider_authority_diagnostics_slice(component, entries)
            or is_engine_depttrans_zone_authority_v1_slice(component, entries)
            or is_engine_provider_target_host_policy_slice(component, entries)
            or is_engine_mcp_execution_profile_decoder_slice(component, entries)
            or is_engine_mcp_telemetry_catalog_slice(component, entries)
            or is_engine_mcp_execution_plan_materialization_slice(
                component,
                entries,
            )
            or is_engine_mcp_execution_plan_telemetry_runtime_slice(
                component,
                entries,
            )
            or is_engine_mcp_execution_plan_module_ownership_slice(
                component,
                entries,
            )
            or is_engine_mcp_normalized_identity_search_slice(
                component,
                entries,
            )
            or is_engine_mcp_l1_credential_reuse_slice(component, entries)
            or is_engine_mcp_l1_credential_provenance_slice(
                component,
                entries,
            )
            or is_engine_mcp_execution_plan_sandbox_runtime_slice(
                component,
                entries,
            )
            or is_engine_mcp_gelios_items_envelope_slice(component, entries)
            or is_engine_mcp_registered_execution_profiles_slice(
                component,
                entries,
            )
            or is_engine_mcp_gelios_units_items_slice(component, entries)
            or is_engine_agent_full_grant_migration_slice(component, entries)
            or is_engine_mcp_control_plane_slice(component, entries)
            or is_engine_mcp_ontology_sdk_slice(component, entries)
            or is_engine_mcp_autonomy_provider_v5_slice(component, entries)
            or is_engine_provider_security_catalog_slice(component, entries)
        )
        and services is not None
    ):
        selected_services = set(services)
        checks = []
        if "app" in selected_services:
            checks.append("http://127.0.0.1:8080/")
        if "nodedc-backend" in selected_services:
            checks.append("http://127.0.0.1:3001/health")
        if is_engine_agent_full_grant_migration_slice(component, entries):
            checks.append("http://127.0.0.1:3001/internal/engine-credential-sink/v1/health")
        return tuple(checks)
    if component == "platform" and entries is not None:
        selected_services = tuple(services) if services is not None else component_services(component, entries)
        # A narrow EDP application deploy must prove only the service it
        # recreated. Unrelated Platform routes retain independent lifecycle and
        # must not turn a valid EDP deploy or rollback into a false failure.
        if selected_services == (EXTERNAL_DATA_PLANE_SERVICE,):
            return (external_data_plane_healthcheck(),)
    checks = list(COMPONENTS[component].get("healthchecks", ()))
    if touches_engine_credential_sink(component, entries):
        checks.append("http://127.0.0.1:3001/internal/engine-credential-sink/v1/health")
    if component == "platform" and entries is not None:
        touches_compose = any(rel == "platform/docker-compose.platform-http.yml" for rel in entries)
        touches_ai_workspace_assistant = any(rel == "platform/ai-workspace-assistant" or rel.startswith("platform/ai-workspace-assistant/") for rel in entries)
        touches_ontology = any(rel == "platform/ontology-core" or rel.startswith("platform/ontology-core/") for rel in entries)
        touches_gelios = any(rel == "platform/gelios-gateway" or rel.startswith("platform/gelios-gateway/") for rel in entries)
        touches_map_gateway = any(rel == "platform/services/map-gateway" or rel.startswith("platform/services/map-gateway/") for rel in entries)
        touches_external_data_plane = touches_external_data_plane_files(entries)
        map_gateway_only_compose = touches_compose and touches_map_gateway and not any((touches_ai_workspace_assistant, touches_ontology, touches_gelios, touches_external_data_plane))
        healthcheck_all_for_compose = touches_compose and not map_gateway_only_compose
        if healthcheck_all_for_compose or touches_ai_workspace_assistant:
            checks.append("http://127.0.0.1:18082/healthz")
        if healthcheck_all_for_compose or touches_ontology:
            checks.append("http://127.0.0.1:18104/healthz")
        if healthcheck_all_for_compose or touches_gelios:
            checks.append("http://127.0.0.1:18105/healthz")
        if touches_map_gateway:
            checks.append({"url": "http://127.0.0.1:18103/healthz", "headers": {"x-nodedc-user-id": "deploy-healthcheck"}})
        if touches_external_data_plane:
            checks.append(external_data_plane_healthcheck())
    return tuple(checks)


def healthcheck_container(container_name):
    last_status = "unknown"
    for _attempt in range(1, 61):
        result = subprocess.run(
            [str(DOCKER), "inspect", "--format", "{{if .State.Health}}{{.State.Health.Status}}{{else}}{{.State.Status}}{{end}}", container_name],
            check=False,
            capture_output=True,
            text=True,
        )
        status_text = result.stdout.strip().lower()
        last_status = status_text or result.stderr.strip() or f"inspect-exit-{result.returncode}"
        if status_text in ("healthy", "running"):
            return
        if status_text in ("unhealthy", "exited", "dead"):
            break
        time.sleep(5)
    die(f"container healthcheck failed for {container_name}: {last_status}")


def compose_service_container_id(component, service):
    result = subprocess.run(
        [*compose_base_cmd(component), "ps", "-q", service],
        cwd=str(component_compose_root(component)),
        check=False,
        capture_output=True,
        text=True,
    )
    container_ids = [line.strip() for line in result.stdout.splitlines() if line.strip()]
    if (
        result.returncode != 0
        or len(container_ids) != 1
        or not re.fullmatch(r"[a-f0-9]{12,64}", container_ids[0])
    ):
        die(f"Compose service container lookup failed: {service}")
    return container_ids[0]


def healthcheck_compose_service(component, service):
    healthcheck_container(compose_service_container_id(component, service))


def container_environment(container, label):
    environment = {}
    for raw in (container.get("Config") or {}).get("Env") or []:
        if not isinstance(raw, str) or "=" not in raw:
            die(f"{label} environment inventory is invalid")
        key, value = raw.split("=", 1)
        if not key or key in environment:
            die(f"{label} environment inventory is invalid")
        environment[key] = value
    return environment


def validate_engine_node_intelligence_secret_mount(container, label):
    matches = [
        mount
        for mount in (container.get("Mounts") or [])
        if isinstance(mount, dict)
        and mount.get("Destination") == ENGINE_NODE_INTELLIGENCE_SECRET_CONTAINER_PATH
    ]
    if len(matches) != 1:
        die(f"{label} secret mount inventory mismatch")
    mount = matches[0]
    if (
        mount.get("Type") != "bind"
        or mount.get("Source") != str(ENGINE_NODE_INTELLIGENCE_SECRET_FILE)
        or mount.get("RW") is not False
    ):
        die(f"{label} secret mount boundary mismatch")


def assert_engine_node_intelligence_container_absent():
    result = subprocess.run(
        [
            str(DOCKER),
            "container",
            "ls",
            "--all",
            "--filter",
            f"label=com.docker.compose.service={ENGINE_NODE_INTELLIGENCE_SERVICE}",
            "--format",
            "{{.ID}}",
        ],
        check=False,
        capture_output=True,
        text=True,
    )
    if result.returncode != 0 or result.stdout.strip():
        die("Engine node-intelligence inactive runtime still has a sidecar container")


def engine_node_intelligence_live_probe_script():
    return """
const {createNodeIntelligenceMcpClient}=await import('file:///app/server/nodeIntelligence/upstreamMcpClient.js');
const client=createNodeIntelligenceMcpClient();
const status=await client.status();
if(!status.ok||status.status!=='ready'||status.authSource!=='file'||status.server?.version!=='2.33.2'||!Object.values(status.capabilities||{}).every(Boolean))throw new Error('status');
const guidance=await client.callTool('get_node',{nodeType:'nodes-base.httpRequest',detail:'minimal'});
if(!guidance||typeof guidance!=='object')throw new Error('guidance');
const nodeValidation=await client.callTool('validate_node',{nodeType:'nodes-base.httpRequest',config:{url:'https://example.com'},mode:'minimal',profile:'ai-friendly'});
if(!nodeValidation||typeof nodeValidation!=='object'||nodeValidation.valid!==true)throw new Error('node-validation');
const workflowValidation=await client.callTool('validate_workflow',{workflow:{name:'NDC acceptance',nodes:[{id:'probe-1',name:'Start',type:'nodes-base.manualTrigger',typeVersion:1,position:[0,0],parameters:{}},{id:'probe-2',name:'Output',type:'nodes-base.set',typeVersion:3.4,position:[240,0],parameters:{}}],connections:{Start:{main:[[{node:'Output',type:'main',index:0}]]}},settings:{}},options:{validateNodes:true,validateConnections:true,validateExpressions:true,profile:'runtime'}});
if(!workflowValidation||typeof workflowValidation!=='object'||workflowValidation.valid!==true)throw new Error('workflow-validation');
process.stdout.write('node-intelligence-live:2.33.2:guidance+node+workflow');
""".strip()


def accept_engine_node_intelligence_runtime(descriptor):
    if descriptor is None or descriptor.get("action") != "activate":
        die("Engine node-intelligence activation descriptor is required")
    validate_installed_engine_node_intelligence_source(descriptor)
    ensure_engine_node_intelligence_secret()
    image = inspect_engine_node_intelligence_image(descriptor)

    sidecar_id = compose_service_container_id(
        "engine",
        ENGINE_NODE_INTELLIGENCE_SERVICE,
    )
    backend_id = compose_service_container_id("engine", "nodedc-backend")
    healthcheck_container(sidecar_id)
    healthcheck_container(backend_id)
    sidecar = inspect_container(sidecar_id)
    backend = inspect_container(backend_id)

    sidecar_config = sidecar.get("Config") or {}
    sidecar_host = sidecar.get("HostConfig") or {}
    sidecar_environment = container_environment(
        sidecar,
        "Engine node-intelligence sidecar",
    )
    if (
        sidecar.get("Image") != image["Id"]
        or sidecar_config.get("Image") != ENGINE_NODE_INTELLIGENCE_IMAGE
        or sidecar_config.get("User")
        != f"{ENGINE_NODE_INTELLIGENCE_RUNTIME_UID}:{ENGINE_NODE_INTELLIGENCE_RUNTIME_GID}"
        or sidecar_host.get("ReadonlyRootfs") is not True
        or sidecar_host.get("PortBindings") not in (None, {})
        or set(sidecar_host.get("CapDrop") or []) != {"ALL"}
        or "no-new-privileges:true" not in (sidecar_host.get("SecurityOpt") or [])
        or sidecar_environment.get("AUTH_TOKEN_FILE")
        != ENGINE_NODE_INTELLIGENCE_SECRET_CONTAINER_PATH
        or sidecar_environment.get("NODE_DB_PATH") != "/app/data/nodes.db"
        or sidecar_environment.get("REBUILD_ON_START") != "false"
        or sidecar_environment.get("N8N_MCP_TELEMETRY_DISABLED") != "true"
    ):
        die("Engine node-intelligence sidecar runtime contract mismatch")
    if any(
        key in sidecar_environment
        for key in ("AUTH_TOKEN", "N8N_API_URL", "N8N_API_KEY")
    ):
        die("Engine node-intelligence sidecar runtime authority leak")
    validate_engine_node_intelligence_secret_mount(
        sidecar,
        "Engine node-intelligence sidecar",
    )

    backend_environment = container_environment(backend, "Engine backend")
    if (
        backend_environment.get("ENGINE_NODE_INTELLIGENCE_MCP_URL")
        != f"http://{ENGINE_NODE_INTELLIGENCE_SERVICE}:3000/mcp"
        or backend_environment.get("ENGINE_NODE_INTELLIGENCE_AUTH_TOKEN_FILE")
        != ENGINE_NODE_INTELLIGENCE_SECRET_CONTAINER_PATH
        or backend_environment.get("ENGINE_NODE_INTELLIGENCE_ASSET_ID")
        != f"nodedc-node-intelligence@{ENGINE_NODE_INTELLIGENCE_RELEASE_ID.replace('-', '+', 1)}"
        or "ENGINE_NODE_INTELLIGENCE_AUTH_TOKEN" in backend_environment
    ):
        die("Engine backend node-intelligence boundary mismatch")
    validate_engine_node_intelligence_secret_mount(
        backend,
        "Engine backend node-intelligence",
    )

    result = run_engine_backend_probe(
        (
            "node",
            "--input-type=module",
            "-e",
            engine_node_intelligence_live_probe_script(),
        ),
        "node-intelligence live capability",
        container_id=backend_id,
    )
    expected = "node-intelligence-live:2.33.2:guidance+node+workflow"
    if result != expected:
        die("Engine node-intelligence live capability acceptance mismatch")
    backend_runtime = preflight_engine_credential_backend_runtime()
    if backend_runtime["mode"] != "verified-derived-retry":
        die("Engine node-intelligence backend immutable runtime acceptance failed")
    return result


def accept_engine_agent_full_grant_migration_runtime():
    expected_scopes = (
        "engine:l2:context:read",
        "engine:l2:graph:read",
        "engine:l2:node-schema:read",
        "engine:l2:graph:plan",
        "engine:l2:graph:write",
        "engine:l2:data-product-publish-grant:plan",
        "engine:l2:data-product-publish-grant:write",
        "engine:l2:validate",
        "engine:l2:runtime:read",
        "engine:l2:deploy-run",
        "engine:l2:execution:stop",
    )
    script = """
import crypto from 'node:crypto';
import fs from 'node:fs';
const file='/app/server/engineAgents/store.js';
const digest=crypto.createHash('sha256').update(fs.readFileSync(file)).digest('hex');
const module=await import('file:///app/server/engineAgents/store.js');
const expected=JSON.parse(process.argv[1]);
if(digest!==process.argv[2]||JSON.stringify(module.ENGINE_AGENT_SCOPES)!==JSON.stringify(expected)||module.ENGINE_AGENT_FULL_DEVELOPER_PROFILE!=='full-developer')process.exit(2);
process.stdout.write('store-v2-full-developer:'+digest);
""".strip()
    result = run_engine_backend_probe(
        (
            "node",
            "--input-type=module",
            "-e",
            script,
            json.dumps(expected_scopes, separators=(",", ":")),
            ENGINE_AGENT_FULL_GRANT_MIGRATION_TARGET_SHA256,
        ),
        "agent full grant migration",
        container_id=engine_backend_container_id(),
    )
    expected = f"store-v2-full-developer:{ENGINE_AGENT_FULL_GRANT_MIGRATION_TARGET_SHA256}"
    if result != expected:
        die("Engine agent full grant migration runtime acceptance mismatch")
    return result


def accept_engine_l2_closed_loop_runtime():
    root = component_root("engine")
    actual = collect_exact_files(
        root,
        ENGINE_L2_CLOSED_LOOP_ARTIFACT_ENTRIES,
        "Engine L2 closed-loop installed target",
    )
    if actual != ENGINE_L2_CLOSED_LOOP_TARGET_SHA256:
        die("Engine L2 closed-loop installed target digest mismatch")

    nginx_actual = collect_exact_files(
        root,
        ("nginx-html/index.html", "nginx-html/assets"),
        "Engine L2 closed-loop nginx target",
    )
    nginx_expected = {
        rel.replace("nodedc-source/dist/", "nginx-html/", 1): digest
        for rel, digest in ENGINE_L2_CLOSED_LOOP_TARGET_SHA256.items()
        if rel.startswith("nodedc-source/dist/")
    }
    if nginx_actual != nginx_expected:
        die("Engine L2 closed-loop nginx target digest mismatch")

    descriptor = current_engine_node_intelligence_descriptor()
    if descriptor is None or descriptor.get("action") != "activate":
        die("Engine L2 closed-loop target descriptor is missing")
    validate_installed_engine_node_intelligence_source(descriptor)

    script = """
const gateway=await import('file:///app/server/routes/engineAgentGateway.js');
const graph=await import('file:///app/server/l2/graphRepository.js');
const n8n=await import('file:///app/server/routes/n8n.js');
const embedded=await import('file:///app/server/routes/ndcAgentMcp.js');
const required=['engine_plan_l2_patch','engine_apply_l2_patch','engine_deploy_and_run','engine_get_node_output_profile'];
const names=new Set(gateway.engineAgentTools.map((tool)=>tool.name));
if(gateway.ENGINE_AGENT_MCP_VERSION!=='0.7.0'||required.some((name)=>!names.has(name)))throw new Error('mcp-catalog');
if(typeof graph.createL2GraphRepository!=='function'||typeof graph.l2GraphRepository?.commit!=='function')throw new Error('graph-repository');
const profile=n8n.toSafeNodeOutputProfile({id:'acceptance',data:{resultData:{runData:{Probe:[{data:{main:[[{json:{value:7,authorization:'must-not-escape'}}]]}}]}}}},'Probe');
if(!profile?.found||profile.valuesIncluded!==false||JSON.stringify(profile).includes('must-not-escape'))throw new Error('safe-output-profile');
const actor=embedded.graphMutationActor({demoAccess:{internal:true},body:{intent:'Deploy acceptance'},get:(name)=>name.toLowerCase()==='x-ndc-actor-plane'?'external_codex_mcp':''});
if(actor.plane!=='external_codex_mcp'||actor.editedBy!=='engine-agent-mcp')throw new Error('external-actor-plane');
process.stdout.write('engine-l2-closed-loop:0.7.0:cas+safe-profile+external-plane');
""".strip()
    result = run_engine_backend_probe(
        (
            "node",
            "--input-type=module",
            "-e",
            script,
        ),
        "Engine L2 closed-loop live contract",
        container_id=engine_backend_container_id(),
    )
    expected = (
        "engine-l2-closed-loop:0.7.0:"
        "cas+safe-profile+external-plane"
    )
    if result != expected:
        die("Engine L2 closed-loop live contract acceptance mismatch")
    backend = preflight_engine_credential_backend_runtime()
    if backend["mode"] != "verified-derived-retry":
        die("Engine L2 closed-loop immutable backend acceptance failed")
    return result


def run_healthchecks(component, entries=None, services=None):
    if is_device_plane_postgres_bootstrap_slice(component, entries):
        if tuple(services or ()) != ("device-postgres",):
            die("Device Plane PostgreSQL bootstrap service set mismatch")
        healthcheck_compose_service("device-plane", "device-postgres")
        return
    if component == "platform" and entries is not None and is_platform_provider_catalog_only(entries):
        return
    if is_engine_l2_closed_loop_slice(component, entries):
        if tuple(services or ()) != ("nodedc-backend", "app"):
            die("Engine L2 closed-loop acceptance service set mismatch")
        for service in services:
            healthcheck_compose_service("engine", service)
        for check in component_healthchecks(component, entries, services):
            healthcheck_url(check)
        accept_engine_l2_closed_loop_runtime()
        return
    if is_engine_n8n_transition(component, entries):
        descriptor = current_engine_n8n_transition_descriptor()
        if descriptor is None:
            die("installed Engine n8n transition descriptor is missing during acceptance")
        accept_engine_n8n_runtime(descriptor)
        return
    if is_engine_node_intelligence_transition(component, entries):
        descriptor = current_engine_node_intelligence_descriptor()
        if descriptor is None:
            die(
                "installed Engine node-intelligence transition descriptor "
                "is missing during acceptance"
            )
        if descriptor["action"] == "activate":
            accept_engine_node_intelligence_runtime(descriptor)
            healthcheck_url("http://127.0.0.1:3001/health")
            return
        healthcheck_compose_service("engine", "nodedc-backend")
        healthcheck_url("http://127.0.0.1:3001/health")
        backend = preflight_engine_credential_backend_runtime()
        if backend["mode"] != "verified-derived-retry":
            die("Engine node-intelligence rollback backend acceptance failed")
        assert_engine_node_intelligence_container_absent()
        return
    touches_publish_grant = is_engine_data_product_publish_grant_slice(
        component,
        entries,
    )
    touches_composite_provider_v4 = is_engine_composite_provider_v4_slice(
        component,
        entries,
    )
    touches_provider_rotating_slot = is_engine_provider_rotating_slot_slice(
        component,
        entries,
    )
    touches_provider_authority_diagnostics = is_engine_provider_authority_diagnostics_slice(
        component,
        entries,
    )
    touches_depttrans_zone_authority_v1 = is_engine_depttrans_zone_authority_v1_slice(
        component,
        entries,
    )
    touches_provider_target_host_policy = is_engine_provider_target_host_policy_slice(
        component,
        entries,
    )
    touches_mcp_execution_profile_decoder = (
        is_engine_mcp_execution_profile_decoder_slice(
            component,
            entries,
        )
    )
    touches_mcp_telemetry_catalog = is_engine_mcp_telemetry_catalog_slice(
        component,
        entries,
    )
    touches_mcp_execution_plan_materialization = (
        is_engine_mcp_execution_plan_materialization_slice(
            component,
            entries,
        )
    )
    touches_mcp_execution_plan_telemetry_runtime = (
        is_engine_mcp_execution_plan_telemetry_runtime_slice(
            component,
            entries,
        )
    )
    touches_mcp_execution_plan_module_ownership = (
        is_engine_mcp_execution_plan_module_ownership_slice(
            component,
            entries,
        )
    )
    touches_mcp_normalized_identity_search = (
        is_engine_mcp_normalized_identity_search_slice(
            component,
            entries,
        )
    )
    touches_mcp_l1_credential_reuse = (
        is_engine_mcp_l1_credential_reuse_slice(component, entries)
    )
    touches_mcp_l1_credential_provenance = (
        is_engine_mcp_l1_credential_provenance_slice(component, entries)
    )
    touches_mcp_execution_plan_sandbox_runtime = (
        is_engine_mcp_execution_plan_sandbox_runtime_slice(component, entries)
    )
    touches_mcp_gelios_items_envelope = (
        is_engine_mcp_gelios_items_envelope_slice(component, entries)
    )
    touches_mcp_registered_execution_profiles = (
        is_engine_mcp_registered_execution_profiles_slice(component, entries)
    )
    touches_mcp_gelios_units_items = (
        is_engine_mcp_gelios_units_items_slice(component, entries)
    )
    touches_agent_grant_migration = is_engine_agent_full_grant_migration_slice(
        component,
        entries,
    )
    touches_mcp_control_plane = is_engine_mcp_control_plane_slice(component, entries)
    touches_mcp_ontology_sdk = is_engine_mcp_ontology_sdk_slice(component, entries)
    touches_mcp_autonomy_provider_v5 = is_engine_mcp_autonomy_provider_v5_slice(component, entries)
    touches_provider_catalog = is_engine_provider_security_catalog_slice(component, entries)
    if (
        touches_engine_credential_sink(component, entries)
        or touches_publish_grant
        or touches_composite_provider_v4
        or touches_provider_rotating_slot
        or touches_provider_authority_diagnostics
        or touches_depttrans_zone_authority_v1
        or touches_provider_target_host_policy
        or touches_mcp_execution_profile_decoder
        or touches_mcp_telemetry_catalog
        or touches_mcp_execution_plan_materialization
        or touches_mcp_execution_plan_telemetry_runtime
        or touches_mcp_execution_plan_module_ownership
        or touches_mcp_normalized_identity_search
        or touches_mcp_l1_credential_reuse
        or touches_mcp_l1_credential_provenance
        or touches_mcp_execution_plan_sandbox_runtime
        or touches_mcp_gelios_items_envelope
        or touches_mcp_registered_execution_profiles
        or touches_mcp_gelios_units_items
        or touches_agent_grant_migration
        or touches_mcp_control_plane
        or touches_mcp_ontology_sdk
        or touches_mcp_autonomy_provider_v5
        or touches_provider_catalog
    ):
        # The HTTP endpoint can become ready before Docker publishes the first
        # successful health probe. Wait for the Compose health barrier before
        # the strict immutable-runtime preflight, both on apply and retry.
        healthcheck_compose_service("engine", "nodedc-backend")
    for url in component_healthchecks(component, entries, services):
        healthcheck_url(url)
    if (
        touches_engine_credential_sink(component, entries)
        or touches_publish_grant
        or touches_composite_provider_v4
        or touches_provider_rotating_slot
        or touches_provider_authority_diagnostics
        or touches_depttrans_zone_authority_v1
        or touches_provider_target_host_policy
        or touches_mcp_execution_profile_decoder
        or touches_mcp_telemetry_catalog
        or touches_mcp_execution_plan_materialization
        or touches_mcp_execution_plan_telemetry_runtime
        or touches_mcp_execution_plan_module_ownership
        or touches_mcp_normalized_identity_search
        or touches_mcp_l1_credential_reuse
        or touches_mcp_l1_credential_provenance
        or touches_mcp_execution_plan_sandbox_runtime
        or touches_mcp_gelios_items_envelope
        or touches_mcp_registered_execution_profiles
        or touches_mcp_gelios_units_items
        or touches_agent_grant_migration
        or touches_mcp_control_plane
        or touches_mcp_ontology_sdk
        or touches_mcp_autonomy_provider_v5
        or touches_provider_catalog
    ):
        runtime = preflight_engine_credential_backend_runtime()
        if runtime["mode"] != "verified-derived-retry":
            die("Engine backend immutable runtime activation acceptance failed")
    if touches_agent_grant_migration:
        accept_engine_agent_full_grant_migration_runtime()
    if touches_mcp_control_plane:
        accept_engine_mcp_control_plane_runtime()
    if touches_mcp_ontology_sdk:
        accept_engine_mcp_ontology_sdk_runtime()
    if touches_mcp_autonomy_provider_v5:
        state = engine_mcp_autonomy_provider_v5_installed_state()
        if state == "target":
            accept_engine_mcp_autonomy_provider_v5_runtime()
    if touches_provider_catalog:
        accept_engine_provider_security_catalog_runtime()
    if touches_publish_grant:
        accept_engine_composite_provider_runtime()
    if touches_composite_provider_v4:
        root = component_root("engine")
        installed_sha256 = {
            rel: sha256_file(root / rel)
            for rel in ENGINE_COMPOSITE_PROVIDER_V4_ARTIFACT_ENTRIES
        }
        if installed_sha256 == ENGINE_COMPOSITE_PROVIDER_V4_TARGET_SHA256:
            if accept_engine_composite_provider_runtime() is None:
                die("Engine composite provider v4 live acceptance was not executed")
        elif installed_sha256 != ENGINE_COMPOSITE_PROVIDER_V4_PREDECESSOR_SHA256:
            die("Engine composite provider v4 installed source state is neither target nor rollback predecessor")
    if touches_provider_rotating_slot:
        root = component_root("engine")
        installed_sha256 = {
            rel: sha256_file(root / rel)
            for rel in ENGINE_PROVIDER_ROTATING_SLOT_ARTIFACT_ENTRIES
        }
        if installed_sha256 == ENGINE_PROVIDER_ROTATING_SLOT_TARGET_SHA256:
            accept_engine_provider_rotating_slot_runtime()
        elif installed_sha256 != ENGINE_PROVIDER_ROTATING_SLOT_PREDECESSOR_SHA256:
            die("Engine provider rotating slot installed state is neither target nor rollback predecessor")
    if touches_provider_authority_diagnostics:
        root = component_root("engine")
        installed_sha256 = {
            rel: sha256_file(root / rel)
            for rel in ENGINE_PROVIDER_AUTHORITY_DIAGNOSTICS_ARTIFACT_ENTRIES
        }
        if installed_sha256 == ENGINE_PROVIDER_AUTHORITY_DIAGNOSTICS_TARGET_SHA256:
            accept_engine_provider_authority_diagnostics_runtime()
        elif installed_sha256 != ENGINE_PROVIDER_AUTHORITY_DIAGNOSTICS_PREDECESSOR_SHA256:
            die("Engine provider authority diagnostics installed state is neither target nor rollback predecessor")
    if touches_depttrans_zone_authority_v1:
        root = component_root("engine")
        target_state = all(
            (root / rel).is_file()
            and not (root / rel).is_symlink()
            and sha256_file(root / rel) == expected
            for rel, expected in ENGINE_DEPTTRANS_ZONE_AUTHORITY_V1_TARGET_SHA256.items()
        )
        predecessor_state = all(
            (root / rel).is_file()
            and not (root / rel).is_symlink()
            and sha256_file(root / rel) == expected
            for rel, expected in ENGINE_DEPTTRANS_ZONE_AUTHORITY_V1_PREDECESSOR_SHA256.items()
        ) and all(
            not (root / rel).exists() and not (root / rel).is_symlink()
            for rel in ENGINE_DEPTTRANS_ZONE_AUTHORITY_V1_NEW_PATHS
        )
        if target_state:
            accept_engine_depttrans_zone_authority_v1_runtime()
        elif not predecessor_state:
            die("Engine Depttrans zone authority v1 installed state is neither target nor rollback predecessor")
    if touches_provider_target_host_policy:
        root = component_root("engine")
        installed_sha256 = {
            rel: sha256_file(root / rel)
            for rel in ENGINE_PROVIDER_TARGET_HOST_POLICY_ARTIFACT_ENTRIES
        }
        if installed_sha256 == ENGINE_PROVIDER_TARGET_HOST_POLICY_TARGET_SHA256:
            accept_engine_provider_target_host_policy_runtime()
        elif installed_sha256 != ENGINE_PROVIDER_TARGET_HOST_POLICY_PREDECESSOR_SHA256:
            die("Engine provider target host policy installed state is neither target nor rollback predecessor")
    if touches_mcp_execution_profile_decoder:
        root = component_root("engine")
        target_state = all(
            (root / rel).is_file()
            and not (root / rel).is_symlink()
            and sha256_file(root / rel) == expected
            for rel, expected in ENGINE_MCP_EXECUTION_PROFILE_DECODER_TARGET_SHA256.items()
        )
        predecessor_state = all(
            (root / rel).is_file()
            and not (root / rel).is_symlink()
            and sha256_file(root / rel) == expected
            for rel, expected in (
                ENGINE_MCP_EXECUTION_PROFILE_DECODER_PREDECESSOR_SHA256.items()
            )
        ) and all(
            not (root / rel).exists() and not (root / rel).is_symlink()
            for rel in ENGINE_MCP_EXECUTION_PROFILE_DECODER_NEW_PATHS
        )
        if target_state:
            accept_engine_mcp_execution_profile_decoder_runtime()
        elif not predecessor_state:
            die(
                "Engine MCP execution profile decoder installed state is neither "
                "target nor rollback predecessor"
            )
    if touches_mcp_telemetry_catalog:
        root = component_root("engine")
        target_state = all(
            (root / rel).is_file()
            and not (root / rel).is_symlink()
            and sha256_file(root / rel) == expected
            for rel, expected in ENGINE_MCP_TELEMETRY_CATALOG_TARGET_SHA256.items()
        ) and all(
            (root / rel).is_file()
            and not (root / rel).is_symlink()
            and sha256_file(root / rel) == expected
            for rel, expected in ENGINE_MCP_TELEMETRY_CATALOG_FOUNDATION_SHA256.items()
        )
        predecessor_state = all(
            (root / rel).is_file()
            and not (root / rel).is_symlink()
            and sha256_file(root / rel) == expected
            for rel, expected in ENGINE_MCP_TELEMETRY_CATALOG_PREDECESSOR_SHA256.items()
        ) and all(
            (root / rel).is_file()
            and not (root / rel).is_symlink()
            and sha256_file(root / rel) == expected
            for rel, expected in ENGINE_MCP_TELEMETRY_CATALOG_FOUNDATION_SHA256.items()
        ) and all(
            not (root / rel).exists() and not (root / rel).is_symlink()
            for rel in ENGINE_MCP_TELEMETRY_CATALOG_NEW_PATHS
        )
        if target_state:
            accept_engine_mcp_telemetry_catalog_runtime()
        elif not predecessor_state:
            die(
                "Engine MCP telemetry catalog installed state is neither target "
                "nor rollback predecessor"
            )
    if touches_mcp_execution_plan_materialization:
        root = component_root("engine")
        target_state = all(
            (root / rel).is_file()
            and not (root / rel).is_symlink()
            and sha256_file(root / rel) == expected
            for rel, expected in (
                ENGINE_MCP_EXECUTION_PLAN_MATERIALIZATION_TARGET_SHA256.items()
            )
        ) and all(
            (root / rel).is_file()
            and not (root / rel).is_symlink()
            and sha256_file(root / rel) == expected
            for rel, expected in (
                ENGINE_MCP_EXECUTION_PLAN_MATERIALIZATION_FOUNDATION_SHA256.items()
            )
        )
        predecessor_state = all(
            (root / rel).is_file()
            and not (root / rel).is_symlink()
            and sha256_file(root / rel) == expected
            for rel, expected in (
                ENGINE_MCP_EXECUTION_PLAN_MATERIALIZATION_PREDECESSOR_SHA256.items()
            )
        ) and all(
            (root / rel).is_file()
            and not (root / rel).is_symlink()
            and sha256_file(root / rel) == expected
            for rel, expected in (
                ENGINE_MCP_EXECUTION_PLAN_MATERIALIZATION_FOUNDATION_SHA256.items()
            )
        ) and all(
            not (root / rel).exists() and not (root / rel).is_symlink()
            for rel in ENGINE_MCP_EXECUTION_PLAN_MATERIALIZATION_NEW_PATHS
        )
        if target_state:
            accept_engine_mcp_execution_plan_materialization_runtime()
        elif not predecessor_state:
            die(
                "Engine MCP execution plan materialization installed state is "
                "neither target nor rollback predecessor"
            )
    if touches_mcp_execution_plan_telemetry_runtime:
        root = component_root("engine")
        target_state = all(
            (root / rel).is_file()
            and not (root / rel).is_symlink()
            and sha256_file(root / rel) == expected
            for rel, expected in (
                ENGINE_MCP_EXECUTION_PLAN_TELEMETRY_RUNTIME_TARGET_SHA256.items()
            )
        ) and all(
            (root / rel).is_file()
            and not (root / rel).is_symlink()
            and sha256_file(root / rel) == expected
            for rel, expected in (
                ENGINE_MCP_EXECUTION_PLAN_TELEMETRY_RUNTIME_FOUNDATION_SHA256.items()
            )
        )
        predecessor_state = all(
            (root / rel).is_file()
            and not (root / rel).is_symlink()
            and sha256_file(root / rel) == expected
            for rel, expected in (
                ENGINE_MCP_EXECUTION_PLAN_TELEMETRY_RUNTIME_PREDECESSOR_SHA256.items()
            )
        ) and all(
            (root / rel).is_file()
            and not (root / rel).is_symlink()
            and sha256_file(root / rel) == expected
            for rel, expected in (
                ENGINE_MCP_EXECUTION_PLAN_TELEMETRY_RUNTIME_FOUNDATION_SHA256.items()
            )
        ) and all(
            not (root / rel).exists() and not (root / rel).is_symlink()
            for rel in ENGINE_MCP_EXECUTION_PLAN_TELEMETRY_RUNTIME_NEW_PATHS
        )
        if target_state:
            accept_engine_mcp_execution_plan_telemetry_runtime()
        elif not predecessor_state:
            die(
                "Engine MCP execution plan telemetry runtime installed state "
                "is neither target nor rollback predecessor"
            )
    if touches_mcp_execution_plan_module_ownership:
        root = component_root("engine")
        target_state = all(
            (root / rel).is_file()
            and not (root / rel).is_symlink()
            and sha256_file(root / rel) == expected
            for rel, expected in (
                ENGINE_MCP_EXECUTION_PLAN_MODULE_OWNERSHIP_TARGET_SHA256.items()
            )
        ) and all(
            (root / rel).is_file()
            and not (root / rel).is_symlink()
            and sha256_file(root / rel) == expected
            for rel, expected in (
                ENGINE_MCP_EXECUTION_PLAN_MODULE_OWNERSHIP_FOUNDATION_SHA256.items()
            )
        )
        predecessor_state = all(
            (root / rel).is_file()
            and not (root / rel).is_symlink()
            and sha256_file(root / rel) == expected
            for rel, expected in (
                ENGINE_MCP_EXECUTION_PLAN_MODULE_OWNERSHIP_PREDECESSOR_SHA256.items()
            )
        ) and all(
            (root / rel).is_file()
            and not (root / rel).is_symlink()
            and sha256_file(root / rel) == expected
            for rel, expected in (
                ENGINE_MCP_EXECUTION_PLAN_MODULE_OWNERSHIP_FOUNDATION_SHA256.items()
            )
        ) and all(
            not (root / rel).exists() and not (root / rel).is_symlink()
            for rel in ENGINE_MCP_EXECUTION_PLAN_MODULE_OWNERSHIP_NEW_PATHS
        )
        if target_state:
            accept_engine_mcp_execution_plan_module_ownership_runtime()
        elif not predecessor_state:
            die(
                "Engine MCP execution plan module ownership installed state "
                "is neither target nor rollback predecessor"
            )
    if touches_mcp_normalized_identity_search:
        root = component_root("engine")
        target_state = all(
            (root / rel).is_file()
            and not (root / rel).is_symlink()
            and sha256_file(root / rel) == expected
            for rel, expected in (
                ENGINE_MCP_NORMALIZED_IDENTITY_SEARCH_TARGET_SHA256.items()
            )
        ) and all(
            (root / rel).is_file()
            and not (root / rel).is_symlink()
            and sha256_file(root / rel) == expected
            for rel, expected in (
                ENGINE_MCP_NORMALIZED_IDENTITY_SEARCH_FOUNDATION_SHA256.items()
            )
        )
        predecessor_state = all(
            (root / rel).is_file()
            and not (root / rel).is_symlink()
            and sha256_file(root / rel) == expected
            for rel, expected in (
                ENGINE_MCP_NORMALIZED_IDENTITY_SEARCH_PREDECESSOR_SHA256.items()
            )
        ) and all(
            (root / rel).is_file()
            and not (root / rel).is_symlink()
            and sha256_file(root / rel) == expected
            for rel, expected in (
                ENGINE_MCP_NORMALIZED_IDENTITY_SEARCH_FOUNDATION_SHA256.items()
            )
        ) and all(
            not (root / rel).exists() and not (root / rel).is_symlink()
            for rel in ENGINE_MCP_NORMALIZED_IDENTITY_SEARCH_NEW_PATHS
        )
        if target_state:
            accept_engine_mcp_normalized_identity_search_runtime()
        elif not predecessor_state:
            die(
                "Engine MCP normalized identity search installed state is "
                "neither target nor rollback predecessor"
            )
    if touches_mcp_l1_credential_reuse:
        root = component_root("engine")
        target_state = all(
            (root / rel).is_file()
            and not (root / rel).is_symlink()
            and sha256_file(root / rel) == expected
            for rel, expected in (
                ENGINE_MCP_L1_CREDENTIAL_REUSE_TARGET_SHA256.items()
            )
        ) and all(
            (root / rel).is_file()
            and not (root / rel).is_symlink()
            and sha256_file(root / rel) == expected
            for rel, expected in (
                ENGINE_MCP_L1_CREDENTIAL_REUSE_FOUNDATION_SHA256.items()
            )
        )
        predecessor_state = all(
            (root / rel).is_file()
            and not (root / rel).is_symlink()
            and sha256_file(root / rel) == expected
            for rel, expected in (
                ENGINE_MCP_L1_CREDENTIAL_REUSE_PREDECESSOR_SHA256.items()
            )
        ) and all(
            (root / rel).is_file()
            and not (root / rel).is_symlink()
            and sha256_file(root / rel) == expected
            for rel, expected in (
                ENGINE_MCP_L1_CREDENTIAL_REUSE_FOUNDATION_SHA256.items()
            )
        ) and all(
            not (root / rel).exists() and not (root / rel).is_symlink()
            for rel in ENGINE_MCP_L1_CREDENTIAL_REUSE_NEW_PATHS
        )
        if target_state:
            accept_engine_mcp_l1_credential_reuse_runtime()
        elif not predecessor_state:
            die(
                "Engine MCP L1 credential reuse installed state is neither "
                "target nor rollback predecessor"
            )
    if touches_mcp_l1_credential_provenance:
        root = component_root("engine")
        target_state = all(
            (root / rel).is_file()
            and not (root / rel).is_symlink()
            and sha256_file(root / rel) == expected
            for rel, expected in (
                ENGINE_MCP_L1_CREDENTIAL_PROVENANCE_TARGET_SHA256.items()
            )
        ) and all(
            (root / rel).is_file()
            and not (root / rel).is_symlink()
            and sha256_file(root / rel) == expected
            for rel, expected in (
                ENGINE_MCP_L1_CREDENTIAL_PROVENANCE_FOUNDATION_SHA256.items()
            )
        )
        predecessor_state = all(
            (root / rel).is_file()
            and not (root / rel).is_symlink()
            and sha256_file(root / rel) == expected
            for rel, expected in (
                ENGINE_MCP_L1_CREDENTIAL_PROVENANCE_PREDECESSOR_SHA256.items()
            )
        ) and all(
            (root / rel).is_file()
            and not (root / rel).is_symlink()
            and sha256_file(root / rel) == expected
            for rel, expected in (
                ENGINE_MCP_L1_CREDENTIAL_PROVENANCE_FOUNDATION_SHA256.items()
            )
        ) and all(
            not (root / rel).exists() and not (root / rel).is_symlink()
            for rel in ENGINE_MCP_L1_CREDENTIAL_PROVENANCE_NEW_PATHS
        )
        if target_state:
            accept_engine_mcp_l1_credential_provenance_runtime()
        elif not predecessor_state:
            die(
                "Engine MCP L1 credential provenance installed state is "
                "neither target nor rollback predecessor"
            )
    if touches_mcp_execution_plan_sandbox_runtime:
        root = component_root("engine")
        target_state = all(
            (root / rel).is_file()
            and not (root / rel).is_symlink()
            and sha256_file(root / rel) == expected
            for rel, expected in (
                ENGINE_MCP_EXECUTION_PLAN_SANDBOX_RUNTIME_TARGET_SHA256.items()
            )
        ) and all(
            (root / rel).is_file()
            and not (root / rel).is_symlink()
            and sha256_file(root / rel) == expected
            for rel, expected in (
                ENGINE_MCP_EXECUTION_PLAN_SANDBOX_RUNTIME_FOUNDATION_SHA256.items()
            )
        )
        predecessor_state = all(
            (root / rel).is_file()
            and not (root / rel).is_symlink()
            and sha256_file(root / rel) == expected
            for rel, expected in (
                ENGINE_MCP_EXECUTION_PLAN_SANDBOX_RUNTIME_PREDECESSOR_SHA256.items()
            )
        ) and all(
            (root / rel).is_file()
            and not (root / rel).is_symlink()
            and sha256_file(root / rel) == expected
            for rel, expected in (
                ENGINE_MCP_EXECUTION_PLAN_SANDBOX_RUNTIME_FOUNDATION_SHA256.items()
            )
        ) and all(
            not (root / rel).exists() and not (root / rel).is_symlink()
            for rel in ENGINE_MCP_EXECUTION_PLAN_SANDBOX_RUNTIME_NEW_PATHS
        )
        if target_state:
            accept_engine_mcp_execution_plan_sandbox_runtime()
        elif not predecessor_state:
            die(
                "Engine MCP execution plan sandbox runtime installed state is "
                "neither target nor rollback predecessor"
            )
    if touches_mcp_gelios_items_envelope:
        root = component_root("engine")
        target_state = all(
            (root / rel).is_file()
            and not (root / rel).is_symlink()
            and sha256_file(root / rel) == expected
            for rel, expected in (
                ENGINE_MCP_GELIOS_ITEMS_ENVELOPE_TARGET_SHA256.items()
            )
        ) and all(
            (root / rel).is_file()
            and not (root / rel).is_symlink()
            and sha256_file(root / rel) == expected
            for rel, expected in (
                ENGINE_MCP_GELIOS_ITEMS_ENVELOPE_FOUNDATION_SHA256.items()
            )
        )
        predecessor_state = all(
            (root / rel).is_file()
            and not (root / rel).is_symlink()
            and sha256_file(root / rel) == expected
            for rel, expected in (
                ENGINE_MCP_GELIOS_ITEMS_ENVELOPE_PREDECESSOR_SHA256.items()
            )
        ) and all(
            (root / rel).is_file()
            and not (root / rel).is_symlink()
            and sha256_file(root / rel) == expected
            for rel, expected in (
                ENGINE_MCP_GELIOS_ITEMS_ENVELOPE_FOUNDATION_SHA256.items()
            )
        ) and all(
            not (root / rel).exists() and not (root / rel).is_symlink()
            for rel in ENGINE_MCP_GELIOS_ITEMS_ENVELOPE_NEW_PATHS
        )
        if target_state:
            accept_engine_mcp_gelios_items_envelope_runtime()
        elif not predecessor_state:
            die(
                "Engine MCP Gelios items envelope installed state is neither "
                "target nor rollback predecessor"
            )
    if touches_mcp_registered_execution_profiles:
        root = component_root("engine")
        target_state = all(
            (root / rel).is_file()
            and not (root / rel).is_symlink()
            and sha256_file(root / rel) == expected
            for rel, expected in (
                ENGINE_MCP_REGISTERED_EXECUTION_PROFILES_TARGET_SHA256.items()
            )
        ) and all(
            (root / rel).is_file()
            and not (root / rel).is_symlink()
            and sha256_file(root / rel) == expected
            for rel, expected in (
                ENGINE_MCP_REGISTERED_EXECUTION_PROFILES_FOUNDATION_SHA256.items()
            )
        )
        predecessor_state = all(
            (root / rel).is_file()
            and not (root / rel).is_symlink()
            and sha256_file(root / rel) == expected
            for rel, expected in (
                ENGINE_MCP_REGISTERED_EXECUTION_PROFILES_PREDECESSOR_SHA256.items()
            )
        ) and all(
            (root / rel).is_file()
            and not (root / rel).is_symlink()
            and sha256_file(root / rel) == expected
            for rel, expected in (
                ENGINE_MCP_REGISTERED_EXECUTION_PROFILES_FOUNDATION_SHA256.items()
            )
        ) and all(
            not (root / rel).exists() and not (root / rel).is_symlink()
            for rel in ENGINE_MCP_REGISTERED_EXECUTION_PROFILES_NEW_PATHS
        )
        if target_state:
            accept_engine_mcp_registered_execution_profiles_runtime()
        elif not predecessor_state:
            die(
                "Engine MCP registered execution profiles installed state is "
                "neither target nor rollback predecessor"
            )
    if touches_mcp_gelios_units_items:
        root = component_root("engine")
        target_state = all(
            (root / rel).is_file()
            and not (root / rel).is_symlink()
            and sha256_file(root / rel) == expected
            for rel, expected in (
                ENGINE_MCP_GELIOS_UNITS_ITEMS_TARGET_SHA256.items()
            )
        ) and all(
            (root / rel).is_file()
            and not (root / rel).is_symlink()
            and sha256_file(root / rel) == expected
            for rel, expected in (
                ENGINE_MCP_GELIOS_UNITS_ITEMS_FOUNDATION_SHA256.items()
            )
        )
        predecessor_state = all(
            (root / rel).is_file()
            and not (root / rel).is_symlink()
            and sha256_file(root / rel) == expected
            for rel, expected in (
                ENGINE_MCP_GELIOS_UNITS_ITEMS_PREDECESSOR_SHA256.items()
            )
        ) and all(
            (root / rel).is_file()
            and not (root / rel).is_symlink()
            and sha256_file(root / rel) == expected
            for rel, expected in (
                ENGINE_MCP_GELIOS_UNITS_ITEMS_FOUNDATION_SHA256.items()
            )
        ) and all(
            not (root / rel).exists() and not (root / rel).is_symlink()
            for rel in ENGINE_MCP_GELIOS_UNITS_ITEMS_NEW_PATHS
        )
        if target_state:
            accept_engine_mcp_gelios_units_items_runtime()
        elif not predecessor_state:
            die(
                "Engine MCP Gelios units items installed state is neither "
                "target nor rollback predecessor"
            )
    container_name = COMPONENTS[component].get("health_container")
    if container_name:
        healthcheck_container(container_name)


def move_artifact(src, target_dir, suffix=""):
    target_dir.mkdir(parents=True, exist_ok=True)
    name = src.name + suffix
    dst = target_dir / name
    if dst.exists():
        dst = target_dir / f"{src.name}.{stamp()}"
    src.rename(dst)
    return dst


def apply_artifact(artifact):
    require_root()
    validate_artifact_location(artifact)
    ensure_layout()

    sha = sha256_file(artifact)
    backup_id = None
    backup_dir = None
    manifest = None
    entries = None
    component = None
    root = None
    services = None
    transition_descriptor = None
    node_intelligence_descriptor = None
    l2_closed_loop_preflight = None
    node_intelligence_service_stopped = False
    apply_started = False
    engine_backend_recreated = False
    engine_backend_initial_mode = None
    runtime_started = False
    current_stamp = stamp()

    with DeployLock():
        try:
            with tempfile.TemporaryDirectory(prefix=f"apply-{current_stamp}-", dir=TMP_DIR) as tmp:
                work = Path(tmp)
                manifest, entries, payload_dir = load_artifact(artifact, work)
                reject_terminal_engine_l2_failed_artifact(manifest, sha)
                patch_id = manifest["id"]
                component = manifest["component"]
                root = component_root(component)
                compose_root = component_compose_root(component)
                bootstrap_root = bool(COMPONENTS[component].get("bootstrap_root"))
                services = component_services(component, entries)
                artifact_only = component_artifact_only(component)

                if state_has_sha(sha):
                    die(f"artifact sha already applied: {sha}")
                if state_has_patch_id(patch_id):
                    die(f"patch id already applied: {patch_id}")
                if is_device_plane_postgres_bootstrap_slice(
                    component,
                    entries,
                ):
                    preflight_device_plane_postgres_bootstrap()
                if not root.is_dir():
                    if bootstrap_root:
                        root.mkdir(parents=True, exist_ok=True)
                    else:
                        die(f"component payload root not found: {root}")
                if is_engine_data_product_publish_grant_slice(component, entries):
                    preflight_engine_data_product_publish_grant_predecessor(payload_dir)
                    publish_backend_preflight = preflight_engine_credential_backend_runtime()
                    if publish_backend_preflight["mode"] != "verified-derived-retry":
                        die("Engine data product publish grant requires the active immutable credential backend")
                if is_engine_composite_provider_v4_slice(component, entries):
                    preflight_engine_composite_provider_v4_predecessor()
                    composite_backend_preflight = preflight_engine_credential_backend_runtime()
                    if composite_backend_preflight["mode"] != "verified-derived-retry":
                        die("Engine composite provider v4 requires the active immutable credential backend")
                if is_engine_provider_rotating_slot_slice(component, entries):
                    preflight_engine_provider_rotating_slot_predecessor()
                    rotating_slot_backend_preflight = preflight_engine_credential_backend_runtime()
                    if rotating_slot_backend_preflight["mode"] != "verified-derived-retry":
                        die("Engine provider rotating slot requires the active immutable credential backend")
                if is_engine_provider_authority_diagnostics_slice(component, entries):
                    preflight_engine_provider_authority_diagnostics_predecessor()
                    authority_diagnostics_backend_preflight = preflight_engine_credential_backend_runtime()
                    if authority_diagnostics_backend_preflight["mode"] != "verified-derived-retry":
                        die("Engine provider authority diagnostics requires the active immutable credential backend")
                if is_engine_depttrans_zone_authority_v1_slice(component, entries):
                    preflight_engine_depttrans_zone_authority_v1_predecessor()
                    depttrans_authority_backend_preflight = preflight_engine_credential_backend_runtime()
                    if depttrans_authority_backend_preflight["mode"] != "verified-derived-retry":
                        die("Engine Depttrans zone authority v1 requires the active immutable credential backend")
                if is_engine_provider_target_host_policy_slice(component, entries):
                    preflight_engine_provider_target_host_policy_predecessor()
                    target_host_policy_backend_preflight = preflight_engine_credential_backend_runtime()
                    if target_host_policy_backend_preflight["mode"] != "verified-derived-retry":
                        die("Engine provider target host policy requires the active immutable credential backend")
                if is_engine_mcp_execution_profile_decoder_slice(component, entries):
                    preflight_engine_mcp_execution_profile_decoder_predecessor()
                    profile_decoder_backend_preflight = (
                        preflight_engine_credential_backend_runtime()
                    )
                    if (
                        profile_decoder_backend_preflight["mode"]
                        != "verified-derived-retry"
                    ):
                        die(
                            "Engine MCP execution profile decoder requires the "
                            "active immutable credential backend"
                        )
                if is_engine_mcp_telemetry_catalog_slice(component, entries):
                    preflight_engine_mcp_telemetry_catalog_predecessor()
                    telemetry_catalog_backend_preflight = (
                        preflight_engine_credential_backend_runtime()
                    )
                    if (
                        telemetry_catalog_backend_preflight["mode"]
                        != "verified-derived-retry"
                    ):
                        die(
                            "Engine MCP telemetry catalog requires the active "
                            "immutable credential backend"
                        )
                if is_engine_mcp_execution_plan_materialization_slice(
                    component,
                    entries,
                ):
                    preflight_engine_mcp_execution_plan_materialization_predecessor()
                    execution_plan_materialization_backend_preflight = (
                        preflight_engine_credential_backend_runtime()
                    )
                    if (
                        execution_plan_materialization_backend_preflight["mode"]
                        != "verified-derived-retry"
                    ):
                        die(
                            "Engine MCP execution plan materialization requires "
                            "the active immutable credential backend"
                        )
                if is_engine_mcp_execution_plan_telemetry_runtime_slice(
                    component,
                    entries,
                ):
                    preflight_engine_mcp_execution_plan_telemetry_runtime_predecessor()
                    execution_plan_telemetry_runtime_backend_preflight = (
                        preflight_engine_credential_backend_runtime()
                    )
                    if (
                        execution_plan_telemetry_runtime_backend_preflight["mode"]
                        != "verified-derived-retry"
                    ):
                        die(
                            "Engine MCP execution plan telemetry runtime "
                            "requires the active immutable credential backend"
                        )
                if is_engine_mcp_execution_plan_module_ownership_slice(
                    component,
                    entries,
                ):
                    preflight_engine_mcp_execution_plan_module_ownership_predecessor()
                    execution_plan_module_ownership_backend_preflight = (
                        preflight_engine_credential_backend_runtime()
                    )
                    if (
                        execution_plan_module_ownership_backend_preflight["mode"]
                        != "verified-derived-retry"
                    ):
                        die(
                            "Engine MCP execution plan module ownership "
                            "requires the active immutable credential backend"
                        )
                if is_engine_mcp_normalized_identity_search_slice(
                    component,
                    entries,
                ):
                    preflight_engine_mcp_normalized_identity_search_predecessor()
                    identity_search_backend_preflight = (
                        preflight_engine_credential_backend_runtime()
                    )
                    if (
                        identity_search_backend_preflight["mode"]
                        != "verified-derived-retry"
                    ):
                        die(
                            "Engine MCP normalized identity search requires "
                            "the active immutable credential backend"
                        )
                if is_engine_mcp_l1_credential_reuse_slice(
                    component,
                    entries,
                ):
                    preflight_engine_mcp_l1_credential_reuse_predecessor()
                    l1_credential_reuse_backend_preflight = (
                        preflight_engine_credential_backend_runtime()
                    )
                    if (
                        l1_credential_reuse_backend_preflight["mode"]
                        != "verified-derived-retry"
                    ):
                        die(
                            "Engine MCP L1 credential reuse requires the "
                            "active immutable credential backend"
                        )
                if is_engine_mcp_l1_credential_provenance_slice(
                    component,
                    entries,
                ):
                    preflight_engine_mcp_l1_credential_provenance_predecessor()
                    l1_credential_provenance_backend_preflight = (
                        preflight_engine_credential_backend_runtime()
                    )
                    if (
                        l1_credential_provenance_backend_preflight["mode"]
                        != "verified-derived-retry"
                    ):
                        die(
                            "Engine MCP L1 credential provenance requires the "
                            "active immutable credential backend"
                        )
                if is_engine_mcp_execution_plan_sandbox_runtime_slice(
                    component,
                    entries,
                ):
                    preflight_engine_mcp_execution_plan_sandbox_runtime_predecessor()
                    execution_plan_sandbox_runtime_backend_preflight = (
                        preflight_engine_credential_backend_runtime()
                    )
                    if (
                        execution_plan_sandbox_runtime_backend_preflight["mode"]
                        != "verified-derived-retry"
                    ):
                        die(
                            "Engine MCP execution plan sandbox runtime requires "
                            "the active immutable credential backend"
                        )
                if is_engine_mcp_gelios_items_envelope_slice(
                    component,
                    entries,
                ):
                    preflight_engine_mcp_gelios_items_envelope_predecessor()
                    gelios_items_envelope_backend_preflight = (
                        preflight_engine_credential_backend_runtime()
                    )
                    if (
                        gelios_items_envelope_backend_preflight["mode"]
                        != "verified-derived-retry"
                    ):
                        die(
                            "Engine MCP Gelios items envelope requires the "
                            "active immutable credential backend"
                        )
                if is_engine_mcp_registered_execution_profiles_slice(
                    component,
                    entries,
                ):
                    preflight_engine_mcp_registered_execution_profiles_predecessor()
                    registered_profiles_backend_preflight = (
                        preflight_engine_credential_backend_runtime()
                    )
                    if (
                        registered_profiles_backend_preflight["mode"]
                        != "verified-derived-retry"
                    ):
                        die(
                            "Engine MCP registered execution profiles requires "
                            "the active immutable credential backend"
                        )
                if is_engine_mcp_gelios_units_items_slice(
                    component,
                    entries,
                ):
                    preflight_engine_mcp_gelios_units_items_predecessor()
                    gelios_units_items_backend_preflight = (
                        preflight_engine_credential_backend_runtime()
                    )
                    if (
                        gelios_units_items_backend_preflight["mode"]
                        != "verified-derived-retry"
                    ):
                        die(
                            "Engine MCP Gelios units items requires the active "
                            "immutable credential backend"
                        )
                if is_engine_agent_full_grant_migration_slice(component, entries):
                    preflight_engine_agent_full_grant_migration_predecessor()
                    migration_backend_preflight = preflight_engine_credential_backend_runtime()
                    if migration_backend_preflight["mode"] != "verified-derived-retry":
                        die("Engine agent full grant migration requires the active immutable credential backend")
                if is_engine_node_intelligence_transition(component, entries):
                    node_intelligence_preflight = preflight_engine_node_intelligence_predecessor(
                        payload_dir
                    )
                    node_intelligence_descriptor = node_intelligence_preflight["descriptor"]
                if is_engine_mcp_control_plane_slice(component, entries):
                    preflight_engine_mcp_control_plane_predecessor(payload_dir)
                if is_engine_mcp_ontology_sdk_slice(component, entries):
                    preflight_engine_mcp_ontology_sdk_predecessor(payload_dir)
                if is_engine_mcp_autonomy_provider_v5_slice(component, entries):
                    preflight_engine_mcp_autonomy_provider_v5_predecessor(payload_dir)
                if is_engine_l2_closed_loop_slice(component, entries):
                    l2_closed_loop_preflight = (
                        preflight_engine_l2_closed_loop_predecessor(payload_dir)
                    )
                if is_engine_provider_security_catalog_slice(component, entries):
                    preflight_engine_provider_security_catalog_predecessor()
                if not artifact_only and not compose_root.is_dir():
                    if bootstrap_root and is_relative_to(compose_root.resolve(strict=False), root.resolve(strict=False)):
                        compose_root.mkdir(parents=True, exist_ok=True)
                    else:
                        die(f"component compose root not found: {compose_root}")
                compose_files = component_compose_files(
                    component,
                    expected_node_intelligence_gateway_sha256=(
                        l2_closed_loop_preflight["partial_gateway_sha256"]
                        if l2_closed_loop_preflight is not None
                        else None
                    ),
                )
                if not artifact_only and compose_files:
                    for compose_file in compose_files:
                        if not compose_file.is_file():
                            compose_entry = None
                            if is_relative_to(compose_file.resolve(strict=False), root.resolve(strict=False)):
                                compose_entry = compose_file.resolve(strict=False).relative_to(root.resolve(strict=False)).as_posix()
                            if compose_entry not in entries:
                                die(f"compose file not found: {compose_file}")
                elif not artifact_only and not (compose_root / "docker-compose.yml").is_file():
                    # A bootstrap component begins with no payload root. Its
                    # compose file may therefore be supplied by the same
                    # reviewed overlay that is about to create that root.
                    compose_entry = None
                    if is_relative_to(compose_root.resolve(strict=False), root.resolve(strict=False)):
                        compose_entry = compose_root.resolve(strict=False).relative_to(root.resolve(strict=False)).joinpath("docker-compose.yml").as_posix()
                    if not (bootstrap_root and compose_entry in entries):
                        die(f"docker-compose.yml not found in component compose root: {compose_root}")
                compose_env_file = component_compose_env_file(component)
                if not artifact_only and compose_env_file and not compose_env_file.is_file():
                    die(f"compose env file not found: {compose_env_file}")
                if not artifact_only and not DOCKER.is_file():
                    die(f"docker not found: {DOCKER}")

                if is_engine_n8n_transition(component, entries):
                    transition_descriptor = read_engine_n8n_transition_descriptor(
                        payload_dir / ENGINE_N8N_TRANSITION_DESCRIPTOR_REL
                    )
                    preflight_engine_n8n_transition(
                        transition_descriptor,
                        enforce_expected_current=True,
                    )
                if touches_engine_credential_sink(component, entries):
                    engine_backend_initial_mode = preflight_engine_credential_backend_runtime()["mode"]

                if COMPONENTS[component].get("immutable_payload"):
                    for rel in entries:
                        destination = root / rel
                        if destination.exists() or destination.is_symlink():
                            die(f"immutable release already exists: {rel}")

                backup_id = safe_name(f"{component}-{patch_id}-{current_stamp}")
                backup_dir = BACKUPS_DIR / backup_id
                backup_dir.mkdir(parents=True, exist_ok=False)
                (backup_dir / "manifest.env").write_text((work / "manifest.env").read_text(encoding="utf-8"), encoding="utf-8")
                (backup_dir / "files.txt").write_text((work / "files.txt").read_text(encoding="utf-8"), encoding="utf-8")

                include_nginx_html = component == "engine" and component_publish_dist(component, entries)
                create_backup(root, backup_dir, entries, include_nginx_html)
                if component == "platform" and touches_external_data_plane_files(entries):
                    validate_backup_partition(
                        entries,
                        read_backup_path_list(backup_dir / "existing-files.txt"),
                        read_backup_path_list(backup_dir / "missing-files.txt"),
                        "Platform pre-apply",
                    )

                apply_started = True
                if (
                    node_intelligence_descriptor is not None
                    and node_intelligence_descriptor["action"] == "rollback-inactive"
                ):
                    stop_and_remove_compose_services(
                        "engine",
                        (ENGINE_NODE_INTELLIGENCE_SERVICE,),
                    )
                    node_intelligence_service_stopped = True
                for rel in entries:
                    copy_payload_path(payload_dir, root, rel, current_stamp)

                if component == "n8n-private-extension":
                    for rel in entries:
                        seal_n8n_private_extension_release(root, rel)

                if component_publish_dist(component, entries):
                    publish_engine_dist(root, current_stamp)

                if touches_engine_credential_sink(component, entries):
                    run_build(component, entries)
                    prepare_component_runtime(component, entries)
                    # From this point the exact immutable override/image are
                    # verified, so even an ambiguous partial Compose failure
                    # can be safely reconciled by recreating on that runtime.
                    engine_backend_recreated = True
                    run_compose(component, services, entries)
                else:
                    # Mark the generic runtime before Compose so a partial
                    # candidate start is always eligible for its domain rollback.
                    runtime_started = bool(services)
                    run_component_runtime(component, entries, services)
                if (
                    l2_closed_loop_preflight is not None
                    and engine_backend_container_id()
                    == l2_closed_loop_preflight["backend_container_id"]
                ):
                    die("Engine L2 closed-loop backend generation was not recreated")
                if (
                    l2_closed_loop_preflight is not None
                    and compose_service_container_id("engine", "app")
                    == l2_closed_loop_preflight["app_container_id"]
                ):
                    die("Engine L2 closed-loop app generation was not recreated")
                run_healthchecks(component, entries, services)

                applied_path = move_artifact(artifact, APPLIED_DIR)
                append_jsonl(STATE_FILE, {
                    "applied_at": utc_now(),
                    "artifact": applied_path.name,
                    "backup_id": backup_id,
                    "component": component,
                    "id": patch_id,
                    "sha256": sha,
                    "status": "ok",
                })
                print(f"deploy-ok patch={patch_id} component={component} backup={backup_id}")
        except Exception as exc:
            rollback_status = "not-required"
            if (
                apply_started
                and backup_dir is not None
                and root is not None
            ):
                if transition_descriptor is not None and is_engine_n8n_transition(component, entries):
                    try:
                        restored_action = restore_engine_n8n_transition(
                            root,
                            backup_dir,
                            entries,
                            transition_descriptor,
                            current_stamp,
                        )
                        rollback_status = f"ok:{restored_action}"
                        print(f"engine-n8n-automatic-rollback={rollback_status}", file=sys.stderr)
                    except Exception as rollback_exc:
                        rollback_status = f"failed:{type(rollback_exc).__name__}"
                        print("engine-n8n-automatic-rollback=failed", file=sys.stderr)
                elif (
                    node_intelligence_descriptor is not None
                    and is_engine_node_intelligence_transition(component, entries)
                ):
                    try:
                        restored_action = rollback_engine_node_intelligence(
                            root,
                            backup_dir,
                            entries,
                            current_stamp,
                            runtime_started=runtime_started,
                            node_intelligence_service_stopped=node_intelligence_service_stopped,
                        )
                        rollback_status = f"ok:{restored_action}"
                        print(
                            f"engine-node-intelligence-automatic-rollback={rollback_status}",
                            file=sys.stderr,
                        )
                    except Exception as rollback_exc:
                        rollback_status = f"failed:{type(rollback_exc).__name__}"
                        print(
                            "engine-node-intelligence-automatic-rollback=failed",
                            file=sys.stderr,
                        )
                elif touches_engine_credential_sink(component, entries):
                    try:
                        restored_action = rollback_engine_credential_bridge(
                            component,
                            root,
                            backup_dir,
                            entries,
                            current_stamp,
                            engine_backend_recreated=engine_backend_recreated,
                            engine_backend_initial_mode=engine_backend_initial_mode,
                        )
                        rollback_status = f"ok:{restored_action}"
                        print(f"engine-credential-automatic-rollback={rollback_status}", file=sys.stderr)
                    except ReconciliationRequired:
                        rollback_status = "deferred:reconciliation-required"
                        print("engine-credential-automatic-rollback=deferred:reconciliation-required", file=sys.stderr)
                    except Exception as rollback_exc:
                        rollback_status = f"failed:{type(rollback_exc).__name__}"
                        print("engine-credential-automatic-rollback=failed", file=sys.stderr)
                elif (
                    l2_closed_loop_preflight is not None
                    and is_engine_l2_closed_loop_slice(component, entries)
                    and services is not None
                ):
                    try:
                        restored_state = (
                            rollback_engine_l2_closed_loop_reconciliation(
                                root,
                                backup_dir,
                                entries,
                                current_stamp,
                                runtime_started,
                                services,
                            )
                        )
                        rollback_status = (
                            "ok:engine-l2-reconciliation:"
                            f"{restored_state}"
                        )
                        print(
                            "engine-l2-automatic-rollback="
                            f"{rollback_status}",
                            file=sys.stderr,
                        )
                    except Exception as rollback_exc:
                        rollback_status = f"failed:{type(rollback_exc).__name__}"
                        print(
                            "engine-l2-automatic-rollback=failed",
                            file=sys.stderr,
                        )
                elif (
                    (
                        is_engine_data_product_publish_grant_slice(component, entries)
                        or is_engine_composite_provider_v4_slice(component, entries)
                        or is_engine_provider_rotating_slot_slice(component, entries)
                        or is_engine_provider_authority_diagnostics_slice(component, entries)
                        or is_engine_depttrans_zone_authority_v1_slice(component, entries)
                        or is_engine_provider_target_host_policy_slice(component, entries)
                        or is_engine_mcp_execution_profile_decoder_slice(
                            component,
                            entries,
                        )
                        or is_engine_mcp_telemetry_catalog_slice(component, entries)
                        or is_engine_mcp_execution_plan_materialization_slice(
                            component,
                            entries,
                        )
                        or is_engine_mcp_execution_plan_telemetry_runtime_slice(
                            component,
                            entries,
                        )
                        or is_engine_mcp_execution_plan_module_ownership_slice(
                            component,
                            entries,
                        )
                        or is_engine_mcp_normalized_identity_search_slice(
                            component,
                            entries,
                        )
                        or is_engine_mcp_l1_credential_reuse_slice(
                            component,
                            entries,
                        )
                        or is_engine_mcp_l1_credential_provenance_slice(
                            component,
                            entries,
                        )
                        or is_engine_mcp_execution_plan_sandbox_runtime_slice(
                            component,
                            entries,
                        )
                        or is_engine_mcp_gelios_items_envelope_slice(
                            component,
                            entries,
                        )
                        or is_engine_mcp_registered_execution_profiles_slice(
                            component,
                            entries,
                        )
                        or is_engine_mcp_gelios_units_items_slice(
                            component,
                            entries,
                        )
                        or is_engine_agent_full_grant_migration_slice(component, entries)
                        or is_engine_mcp_control_plane_slice(component, entries)
                        or is_engine_mcp_ontology_sdk_slice(component, entries)
                        or is_engine_mcp_autonomy_provider_v5_slice(component, entries)
                        or is_engine_provider_security_catalog_slice(component, entries)
                    )
                    and services is not None
                ):
                    try:
                        restored_state = rollback_engine_apply(
                            root,
                            backup_dir,
                            entries,
                            current_stamp,
                            runtime_started,
                            services,
                        )
                        rollback_status = f"ok:engine-overlay:{restored_state}"
                        print(f"engine-automatic-rollback={rollback_status}", file=sys.stderr)
                    except Exception as rollback_exc:
                        rollback_status = f"failed:{type(rollback_exc).__name__}"
                        print("engine-automatic-rollback=failed", file=sys.stderr)
                elif (
                    component == "platform"
                    and entries is not None
                    and services is not None
                    and touches_external_data_plane_files(entries)
                ):
                    try:
                        restored_state = rollback_platform_apply(
                            root,
                            backup_dir,
                            entries,
                            current_stamp,
                            runtime_started,
                            services,
                        )
                        rollback_status = f"ok:platform-overlay:{restored_state}"
                        print(f"platform-automatic-rollback={rollback_status}", file=sys.stderr)
                    except Exception as rollback_exc:
                        rollback_status = f"failed:{type(rollback_exc).__name__}"
                        print("platform-automatic-rollback=failed", file=sys.stderr)
                elif (
                    component == "device-plane"
                    and entries is not None
                    and services is not None
                ):
                    try:
                        restored_state = rollback_device_plane_apply(
                            root,
                            backup_dir,
                            entries,
                            current_stamp,
                            runtime_started,
                            services,
                        )
                        rollback_status = f"ok:device-plane-overlay:{restored_state}"
                        print(
                            f"device-plane-automatic-rollback={rollback_status}",
                            file=sys.stderr,
                        )
                    except Exception as rollback_exc:
                        rollback_status = f"failed:{type(rollback_exc).__name__}"
                        print(
                            "device-plane-automatic-rollback=failed",
                            file=sys.stderr,
                        )
            failed_path = None
            if artifact.exists() and rollback_status != "deferred:reconciliation-required":
                try:
                    failed_path = move_artifact(artifact, FAILED_DIR, suffix=f".{current_stamp}")
                except Exception:
                    failed_path = None

            append_jsonl(FAILED_STATE_FILE, {
                "artifact": str(failed_path.name if failed_path else artifact.name),
                "backup_id": backup_id,
                "component": manifest.get("component") if manifest else None,
                "failed_at": utc_now(),
                "id": manifest.get("id") if manifest else None,
                "message": str(exc),
                "rollback_status": rollback_status,
                "sha256": sha,
                "started_apply": apply_started,
                "status": (
                    "reconciliation-required"
                    if rollback_status == "deferred:reconciliation-required"
                    else "failed"
                ),
            })
            if backup_id:
                print(f"backup={backup_id}", file=sys.stderr)
            raise


def main(argv):
    if sys.version_info < (3, 8):
        die("Python 3.8 or newer is required")
    parser = argparse.ArgumentParser(prog="nodedc-deploy")
    sub = parser.add_subparsers(dest="cmd", required=True)

    plan = sub.add_parser("plan")
    plan.add_argument("artifact")

    apply = sub.add_parser("apply")
    apply.add_argument("artifact")

    sub.add_parser("verify-install")

    args = parser.parse_args(argv)

    if args.cmd == "verify-install":
        verify_install()
        return 0

    artifact = Path(args.artifact).absolute()
    if args.cmd == "plan":
        plan_artifact(artifact)
        return 0
    if args.cmd == "apply":
        apply_artifact(artifact)
        return 0

    parser.print_help()
    return 2


if __name__ == "__main__":
    try:
        raise SystemExit(main(sys.argv[1:]))
    except DeployError as exc:
        print(f"ERROR: {exc}", file=sys.stderr)
        raise SystemExit(1)
