{
  "schema_version": "2.0",
  "build": "NP176-AUTHOR-SCENARIOS-SERVICE-GATE",
  "status": "PREPARED_ROLLBACK_CONTRACT_NOT_EXECUTED_FOR_THIS_BUILD",
  "rollback_target": {
    "version": "NP176-I26-frozen",
    "file_count": 45,
    "bundle_sha256": "5083863fc53c4b0eb2d6f92225768e9c9c9465977abee4201e957dbcfdf865fa",
    "index_sha256": "490eff38237dd1b85c6413671df206c4b2ffe1d7d26d75d54166dde5a6bf98f6"
  },
  "strategy": [
    "verify live I26 byte-for-byte before mutation",
    "stage and verify the exact candidate build in a sibling directory",
    "atomically exchange I26 and candidate directories",
    "verify candidate locally and publicly",
    "atomically restore and verify exact I26",
    "reactivate and verify the same candidate bytes",
    "commit only after all checks pass; otherwise restore I26"
  ],
  "stop_conditions": [
    "authorized bundle hash differs",
    "live baseline differs from the declared 45-file I26 manifest",
    "archive contains unsafe names, duplicates, links or special files",
    "atomic exchange support is unavailable",
    "nginx configuration fingerprint changes or nginx -t fails",
    "any local, remote or public hash differs",
    "transaction lock cannot be acquired"
  ],
  "allowed_terminal_states": [
    "PASS_FINAL_LIVE_I26_ROLLBACK_PROVED",
    "FAILED_I26_RESTORED_AND_PROVED",
    "RECOVERY_UNPROVED"
  ],
  "criterion_49_rule": "PASS only for the exact build hash in a successful external publication-and-rollback record; otherwise UNKNOWN.",
  "scope": "The current candidate is identified by publication_build.json and publication_freeze_manifest.json. Historical FINAL event names are controller protocol labels only."
}
