Skip to content

m5-cutover sidecar: closed file with unreleased lease is treated as a new attempt (overlapping-scope, no recovery hint) #516

Closed

Description

@James3014

Problem (liveness, not safety)

After a crash between the cutover file close and the SQLite intent/lease finalization, the file can read phase: "closed" while the state-root effect lease is still held (not yet terminal). The two stores are separate.

scripts/ops/m5-cutover/m5-cutover-lib.mjs:76 selectMode:

if (!file || file.phase === "closed") return "full"; // Branch a: brand-new attempt.

So the sidecar treats this state as a brand-new attempt, issues a new prepare, and fails with overlapping resource scope is already leased (same symptom as #472). The Refuse recovery hint does not tell the operator that re-running finish / lease replay is the fix.

Why it is not a safety bug

Found during offline fault injection (T4, faults F5 close-crash and F7 release-failure) on main f7cfc4777fea59601ab546399fc86c47ad705d26. All 7 injected faults were SAFE: the file close is gated on observed identity + witness, the lease side fails closed, and replay completes it. Only the operator path gets stuck.

Suggested fix

In selectMode, when file.phase === "closed" but the terminal effect lease for that cutover is not released, return a resume_finish/lease-replay mode (or Refuse with a hint naming cutover release-terminal-lease / finish replay) instead of "full". Add a case to m5-cutover.test.mjs.

Evidence

Activity

  1. github-actions commented on Oct 14, 2026

    @github-actions

    Authority: RESEARCH_OBSERVATION_ONLY / NO_ENGINEERING_AUTHORITY

    Hybrid replication capture receipt
    {
      "body_gzip_base64": "H4sIAAAAAAACA21US3PbNhC+61dsrYvkiKRl61Er44M7Y880k05by50eAwhcinBAgAOAktXJj+8uQSVx2huJXezu91iMx/CHdzuDDUyMPqDFEGZgXYQgK4yn6ei+iuhBgvIy1LDDeES0EGsE1UV3oNjlZaUNXl6CMi4gSFv24e2fH3VE0DaijYVBSbFKW2n0PzJqZ2d9Fl8FJS14lCWItqa0DVz0pcoLAceaEzgzRBkx845mw6pCFSHV1IFC2hio0ZQw4dlPGIGmbrjbNIdnuh2PjtKcxwDSUzFspad6+WgkgvK6jaFwbSiaZTbA+u4zM3qXNy9hs14JEAENNf/NlSg2IyHESxjpCiY/9Ui+fOkR5T0OuLu7+wplSghj5y1cVJ0xF++hKOAXL62qQW5gR19lZvEIMkZs2phz6dHWJei6RCU9RCIpBjrqMdP4IAnOfy/PiJTQMVTg09YzWpz10lRSmwBHHWsQDM7IttV2T9MF13lFzZRre1alYU1OieZSwCTIhsInauAa7jxerK8HesUTVl1AQWUUVz1BTcJD6WgIViQiCcRQqDbx7ghLLSNlZ76zlvuTNTQZrBhUpZGNPPEYySWvpNR4DH/XdBb5mKvKwaWw6/ajR9cRvLLzXM1VldGWLsrOULp9IcnIczB5XszSYYDHZXJslqzN5DyuqXE/QMY8dR6nQLcaqS2Iaq0qtViv1xXK5e3qai53y8Xq5va2Uj+vKCDL9dWyvF6JHO4J7Xpoi+W54RHJedv7x4fNd9bvd4bw7CVnUjO3C+gP9E2i26gJ3TuWK20m30sEsScGMZPDkrwDb8o1rcFI7OuYw+/WnN6y30rSf4+RfdSpz4ncbbffY+gH1q+jX+0br89oFZFZ+H97C9Ig9j3Oi/d2S6uz5OdXY5BwoJumH9ZDgiArdg1+So4Q6enIBmANzQITKvbVcb2VZfKblQ2rL85NzmKeZ8r6X0EuG+yWqk5JKsJND5CrQKQFZRXLkh8+Hj86EN8ehJyIjfwiiETcw4G1UjjKYL5MamffPMfJASYieFXERfZDONWKQaRnl4RrNG1xOSWNQmBDDL57z8M6z26GD7SJ4eZqvig+W3c0WO5pBS2+dqEg8lB6VRfXV9erbH6VzRdZnMdF8bz49PSw/evjc97wMit5oMcEbqY5Tf2Ehu236VeaYr2m0xn9zpf56F8VXFjdJQYAAA==",
      "capture_sha256": "cee1658ff0531bf6bc1780e66e2158e2a84f4defde269b439bc6c610ba5e059b",
      "captured_at": "2026-10-14T05:54:56Z",
      "contract_sha256": "f7057affad0ae1335e6821296623f63d5cdc095d6de32a5ed498e7f60c912f39",
      "created_at": "2026-10-14T05:54:49Z",
      "default_branch": "main",
      "issue_number": 516,
      "issue_updated_at": "2026-10-14T05:54:49Z",
      "pre_implementation_revision": "f7cfc4777fea59601ab546399fc86c47ad705d26",
      "repository": "James3014/devspace",
      "schema": "nexus.hybrid_replication.capture.v1",
      "source_event_id": "actions:38519204900:1",
      "title": "m5-cutover sidecar: closed file with unreleased lease is treated as a new attempt (overlapping-scope, no recovery hint)"
    }
  2. github-actions commented on Oct 14, 2026

    @github-actions

    Authority: RESEARCH_OBSERVATION_ONLY / NO_ENGINEERING_AUTHORITY

    {
      "activation_boundary": "2026-10-13T04:05:51Z",
      "activation_state": "AUTOMATIC_CAPTURE_READY",
      "admitted_at": "2026-10-14T05:54:56Z",
      "capture_sha256": "cee1658ff0531bf6bc1780e66e2158e2a84f4defde269b439bc6c610ba5e059b",
      "disposition": "ADMITTED_PRIMARY_FRESH_TASK",
      "exclusion_set_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
      "implementation_pr_numbers": [],
      "issue_state_at_admission": "open",
      "receipt_sha256": "ceb2d4e4a36a152c28f33d7144fa5fd32990629c006c9f8aeb0b36319bafed3a",
      "schema": "nexus.hybrid_replication.admission.v1",
      "task_key": "James3014/devspace#516",
      "tracked_parent_created_at": null,
      "tracked_parent_issue_number": null
    }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions