{
  "synthetic": true,
  "execution": "Teaching record only; no live integration tested",
  "slug": "website-rebuild-environment-handover",
  "group": "supplier-handover",
  "title": [
    "A source handover must include the rebuild environment",
    "交付源码，也要交清重建环境"
  ],
  "intro": [
    "Receiving a Git archive does not prove another supplier can rebuild the website. A lockfile, runtime, package-manager version and install flags can determine a different dependency tree. Commission a reproducible handover receipt without placing registry tokens or production secrets in the archive.",
    "拿到Git归档，不证明另一供应商能重建网站。锁文件、运行环境、包管理器及安装参数可能决定不同依赖树。应验收可重建的交付记录，但不能把仓库令牌或生产秘密放进归档。"
  ],
  "facts": [
    [
      "npm ci requires an existing lockfile, errors when it conflicts with package.json and does not rewrite those files. npm documents that dependency-tree-affecting flags used when making the lockfile may need to be supplied again.",
      "npm ci要求现有锁文件，与package.json冲突时失败且不重写两者；影响依赖树的原安装参数可能须再次提供。",
      "https://docs.npmjs.com/cli/v11/commands/npm-ci/"
    ]
  ],
  "example": [
    [
      [
        "Synthetic manifest: Node22.13.0, npm11, lockSHA=L1",
        "Recorded install flag: legacy-peer-deps=true",
        "Handover contains versions, lock identity and reviewed flag"
      ],
      [
        "合成清单：Node22.13.0、npm11、锁hash为L1",
        "安装参数legacy-peer-deps=true",
        "交付记录包含版本、锁身份及已审参数"
      ]
    ],
    [
      [
        "package.json changed; lock stillL1",
        "Dependency declarations disagree",
        "npm ci should fail; do not silently update lock to hide it"
      ],
      [
        "package.json已变，锁仍L1",
        "依赖声明不一致",
        "ci应失败，不能静默改锁掩盖"
      ]
    ],
    [
      [
        "Install succeeds; build output differs",
        "Different environment/input evidence",
        "Investigate; install success is not identical build proof"
      ],
      [
        "安装成功但构建输出不同",
        "环境或输入证据不同",
        "继续调查，安装成功不证明构建相同"
      ]
    ],
    [
      [
        "Archive includes a real registry token",
        "Credential detected",
        "Stop handover and arrange owner-controlled secret handling"
      ],
      [
        "归档含真实仓库令牌",
        "检测到凭证",
        "暂停交付，按负责人流程处理秘密"
      ]
    ]
  ],
  "steps": [
    [
      "Record source commit, lockfile hash, runtime/package-manager versions, required non-secret configuration and install/build commands. Separate secret provisioning from source delivery.",
      "记录源码提交、锁hash、环境版本、必要非秘密配置及安装构建命令；秘密配置另行交付。"
    ],
    [
      "Have the replacement supplier rebuild in an authorised isolated clean environment and retain exit status, dependency resolution and artefact hashes. Do not run install scripts from unknown projects without review.",
      "由接手方在获准隔离干净环境重建，保留退出状态、依赖解析及产物hash；未知项目安装脚本须先审查。"
    ],
    [
      "Compare representative routes and required runtime bindings after the build. Treat external APIs, storage and deployment permissions as separate handover items.",
      "构建后核对代表路由及运行绑定；外部API、存储及部署权限另列交付项。"
    ]
  ],
  "result": [
    "The filled manifest tells a second supplier what to reproduce. It does not guarantee bit-for-bit output from every toolchain or that a working build can deploy without external services. The conflicting-lock row is an intended failure that protects the approved dependency record.",
    "已填清单让接手方知道要复现什么，但不保证所有工具链逐位相同，也不保证无外部服务即可部署。锁冲突是预期失败，用于保护批准依赖记录。"
  ],
  "accept": [
    "Require a redacted clean rebuild receipt and a separately verified runtime handover. A ZIP file or an install success badge is insufficient.",
    "须有脱敏干净重建回执及独立运行交接验证；ZIP或安装成功标志不足。"
  ],
  "limit": [
    "Synthetic environment identifiers, not instructions to replace this site’s frozen dependencies. No installation, token transfer, upgrade or production rebuild is executed by the example.",
    "合成环境标识，不指导替换本站冻结依赖；例子未安装、传令牌、升级或重建生产。"
  ],
  "oldLinks": [
    {
      "language": "en",
      "target": "/en/scenarios/backup-restore-drill/",
      "anchor": "Plan a separate restore drill for data and services",
      "reason": "A source rebuild does not restore databases, uploads or external services."
    },
    {
      "language": "zh",
      "target": "/zh/scenarios/backup-restore-drill/",
      "anchor": "数据与外部服务还须另做恢复演练",
      "reason": "Source rebuild and data/service restoration are separate next decisions."
    }
  ]
}
