{
  "schema": 1,
  "sqlstate": "40P01",
  "condition_name": "deadlock_detected",
  "sources": [
    {
      "commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
      "id": "src.errcodes.18.6",
      "location": "lines 329-334",
      "path": "src/backend/utils/errcodes.txt",
      "sha256": "6e8de346643ba84aa3c9c6a73360acfc7b2dfb89162c06c08ce9bf5bcd5bbcba",
      "tag": "REL_18_6",
      "url": "https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/errcodes.txt"
    },
    {
      "commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
      "id": "src.deadlock.18.6",
      "location": "lines 1071-1138",
      "path": "src/backend/storage/lmgr/deadlock.c",
      "sha256": "f9931d72369a752e5fff5df3b5bfe5ffd47a3f65651522d27cf62f75fac0075f",
      "tag": "REL_18_6",
      "url": "https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/storage/lmgr/deadlock.c#L1071-L1138"
    },
    {
      "commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
      "id": "doc.mvcc.18",
      "location": "serialization and deadlock failure handling",
      "path": "doc/src/sgml/mvcc.sgml",
      "sha256": "4b7bf77ee0af4b86052330ff2421d567df3604b75fe7d4f522bec84fdea87340",
      "tag": "PG18-docs",
      "url": "https://www.postgresql.org/docs/18/mvcc-serialization-failure-handling.html"
    },
    {
      "commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
      "id": "doc.protocol.18",
      "location": "ErrorResponse fields",
      "path": "doc/src/sgml/protocol.sgml",
      "sha256": "745339e07ebbc2bb67d98b258e25772ada644ef26011e3cd6b3fcbb435235f89",
      "tag": "PG18-docs",
      "url": "https://www.postgresql.org/docs/18/protocol-error-fields.html"
    },
    {
      "id": "manifest.40P01",
      "kind": "local_artifact",
      "location": "snapshots and definition_blobs entries for the 40P01 definition",
      "sha256": "1727a275f336988ff96b4f9990a4ca253080f73fc5d316e7def165c8cf3708a8"
    },
    {
      "id": "case-manifest.40P01",
      "kind": "local_artifact",
      "location": "two_session_lock_cycle",
      "sha256": "85a8653680509a53f9d8fa9b08bafa3eeabe78553ef7d1f4e0aaf0ef7a1abe3d"
    },
    {
      "id": "snippet-registry.40P01.final",
      "kind": "local_artifact",
      "location": "two_session_lock_cycle ordered SQL",
      "sha256": "71a3377497dc2c1ba5b71c9ba81f71fc3cff975fcd245613ba2ddb82857c0591"
    }
  ],
  "claims": [
    {
      "id": "identity.class-and-condition",
      "limits": "Directory identity does not identify the lock graph or the selected victim.",
      "method": "Read the Class 40 section and 40P01 row in the frozen errcodes.txt snapshot.",
      "sources": [
        "src.errcodes.18.6"
      ],
      "statement": "40P01 is the deadlock_detected condition in Class 40 transaction_rollback."
    },
    {
      "id": "mechanism.deadlock-report",
      "limits": "The detail contains live process and transaction identifiers and is not a fixed user-facing template.",
      "method": "Trace DeadLockReport and compare the primary message, dynamic detail, hint, and source location in the victim diagnostic.",
      "sources": [
        "src.deadlock.18.6",
        "doc.protocol.18"
      ],
      "statement": "The deadlock detector reports deadlock detected with a dynamically assembled wait-graph detail and the hint See server log for query details."
    },
    {
      "id": "runtime.cycle-and-recovery",
      "limits": "The survivor's winner can differ by timing; the run proves the controlled cycle and recovery, not a universal victim-selection rule.",
      "method": "Use an explicit barrier, observe transactionid Lock waits through pg_stat_activity, then inspect worker diagnostics, transaction states, and surviving rows.",
      "sources": [
        "doc.mvcc.18",
        "case-manifest.40P01",
        "runtime.40P01-manual-boundary-final-20260909.latest",
        "runtime.40P01-manual-boundary-final-20260909.pg10"
      ],
      "statement": "An explicit two-session lock cycle produced one 40P01 victim in INERROR, left one coherent survivor transaction, and allowed the victim to recover with ROLLBACK."
    },
    {
      "id": "runtime.complete-retry",
      "limits": "A fixed ordered update is a repair proof for this case; application retries still need complete business-operation and idempotency review.",
      "method": "Run the retry statements in primary-key order on a fresh transaction and assert IDLE plus both post-retry rows.",
      "sources": [
        "doc.mvcc.18",
        "snippet-registry.40P01.final",
        "runtime.40P01-registry-final-20260909.latest",
        "runtime.40P01-registry-final-20260909.pg10",
        "runtime.40P01-manual-boundary-final-20260909.latest",
        "runtime.40P01-manual-boundary-final-20260909.pg10"
      ],
      "statement": "After the deadlock cleanup, an ordered retry transaction updated both rows, committed, and produced retry-1 and retry-2."
    },
    {
      "id": "versions.catalogue-boundary",
      "limits": "The first scanned release is a lower bound, not an asserted introduction version.",
      "method": "Read the manifest snapshots and definition references for the code.",
      "sources": [
        "manifest.40P01"
      ],
      "statement": "The locked catalogue records 40P01 in every listed formal snapshot from 9.0.23 through 18.6 and in 19beta3; pre-9.0 history is not scanned."
    }
  ],
  "messages": [
    {
      "detail_template": "%s",
      "detail_type": "dynamic wait graph",
      "hint_template": "See server log for query details.",
      "id": "message.deadlock-report",
      "limits": "The source passes the assembled client wait graph through errdetail_internal(\"%s\", clientbuf.data); process, transaction, relation, and tuple values vary by run.",
      "primary_template": "deadlock detected",
      "severity_source": "explicit ERROR",
      "sources": [
        "src.deadlock.18.6"
      ],
      "sqlstate": "40P01"
    }
  ],
  "usage_evidence": [
    {
      "evidence_ids": [
        "identity.class-and-condition",
        "src.errcodes.18.6"
      ],
      "scope": "SQLSTATE directory identity",
      "status": "definition_only"
    },
    {
      "evidence_ids": [
        "mechanism.deadlock-report",
        "src.deadlock.18.6",
        "doc.protocol.18"
      ],
      "scope": "Deadlock report construction and dynamic detail",
      "status": "source_path_confirmed"
    },
    {
      "evidence_ids": [
        "runtime.cycle-and-recovery",
        "runtime.complete-retry",
        "snippet-registry.40P01.final",
        "runtime.40P01-registry-final-20260909.latest",
        "runtime.40P01-registry-final-20260909.pg10"
      ],
      "scope": "Two-session lock cycle, transaction recovery, and ordered retry",
      "status": "observed_runtime"
    },
    {
      "evidence_ids": [
        "versions.catalogue-boundary",
        "manifest.40P01"
      ],
      "scope": "Version presence",
      "status": "definition_only"
    }
  ],
  "runtime": [
    {
      "cases": [
        "two_session_lock_cycle"
      ],
      "id": "runtime.40P01-registry-final-20260909.latest",
      "observed": {
        "lock_wait": {
          "wait_event": "transactionid",
          "wait_event_type": "Lock"
        },
        "synchronization": "Both workers first held one row lock; a barrier then released the two cross-row requests, while an independent observer sampled the transactionid lock waits. The observer did not release the requests.",
        "retry": {
          "rows": [
            [
              1,
              "retry-1"
            ],
            [
              2,
              "retry-2"
            ]
          ],
          "status": "IDLE"
        },
        "rows_before_retry": [
          [
            1,
            "first-1"
          ],
          [
            2,
            "first-2"
          ]
        ],
        "statuses": {
          "survivor": "IDLE",
          "victim_after_error": "INERROR",
          "victim_after_rollback": "IDLE"
        },
        "victim": {
          "message_hint": "See server log for query details.",
          "message_primary": "deadlock detected",
          "severity": "ERROR",
          "source_file": "deadlock.c",
          "source_function": "DeadLockReport",
          "source_line": "1138",
          "sqlstate": "40P01",
          "worker": "second"
        }
      },
      "raw_sha256": "bdfda4fc40404195f34d3297cf71eebdd2146ea44bf91fc58484498455a5953d",
      "run_id": "40P01-registry-final-20260909",
      "server_version": "18.6 (Homebrew)",
      "server_version_num": 180006,
      "snippet_registry": {
        "sha256": "71a3377497dc2c1ba5b71c9ba81f71fc3cff975fcd245613ba2ddb82857c0591"
      },
      "status": "passed",
      "summary_sha256": "693bc9cc5696cbb892eb12808a2b15db875c52aad5961410f59679df63566c07",
      "target": "latest"
    },
    {
      "cases": [
        "two_session_lock_cycle"
      ],
      "id": "runtime.40P01-registry-final-20260909.pg10",
      "image": "postgres@sha256:b2baf8998630663d21370da06387c950e587071bdd307ee34e661cdcc7442bcc",
      "observed": {
        "lock_wait": {
          "wait_event": "transactionid",
          "wait_event_type": "Lock"
        },
        "synchronization": "Both workers first held one row lock; a barrier then released the two cross-row requests, while an independent observer sampled the transactionid lock waits. The observer did not release the requests.",
        "retry": {
          "rows": [
            [
              1,
              "retry-1"
            ],
            [
              2,
              "retry-2"
            ]
          ],
          "status": "IDLE"
        },
        "rows_before_retry": [
          [
            1,
            "second-1"
          ],
          [
            2,
            "second-2"
          ]
        ],
        "statuses": {
          "survivor": "IDLE",
          "victim_after_error": "INERROR",
          "victim_after_rollback": "IDLE"
        },
        "victim": {
          "message_hint": "See server log for query details.",
          "message_primary": "deadlock detected",
          "severity": "ERROR",
          "source_file": "deadlock.c",
          "source_function": "DeadLockReport",
          "source_line": "1146",
          "sqlstate": "40P01",
          "worker": "first"
        }
      },
      "raw_sha256": "33e4c878282a503d074da04aaceb11f0aa5d0a245cac601562a5ea847cd45f63",
      "run_id": "40P01-registry-final-20260909",
      "server_version": "10.21 (Debian 10.21-1.pgdg90+1)",
      "server_version_num": 100021,
      "snippet_registry": {
        "sha256": "71a3377497dc2c1ba5b71c9ba81f71fc3cff975fcd245613ba2ddb82857c0591"
      },
      "status": "passed",
      "summary_sha256": "ff489619acc2047333c05a4d565a0ad4c993a762b8c4abca3fe684cd8928cf0c",
      "target": "pg10"
    },
    {
      "cases": [
        "two_session_lock_cycle"
      ],
      "id": "runtime.40P01-manual-boundary-final-20260909.latest",
      "limits": "This run proves the registry BEGIN/COMMIT/ROLLBACK statements for both lock-cycle sessions and the ordered retry execute with autocommit=True; worker synchronization still uses barriers and observed lock waits.",
      "observed": {
        "connections_autocommit": {
          "first": true,
          "retry": true,
          "second": true
        },
        "retry": {
          "rows": [
            [
              1,
              "retry-1"
            ],
            [
              2,
              "retry-2"
            ]
          ],
          "status": "IDLE"
        },
        "transaction_control": "Registry BEGIN/COMMIT/ROLLBACK statements run with autocommit=True; no driver implicit BEGIN participates."
      },
      "raw_sha256": "562a80715a6dcaf4f14d99c54001799e05c3c52353d9e836ab88039f47ce2cb5",
      "run_id": "40P01-manual-boundary-final-20260909",
      "server_version": "18.6 (Homebrew)",
      "server_version_num": 180006,
      "snippet_registry": {
        "sha256": "71a3377497dc2c1ba5b71c9ba81f71fc3cff975fcd245613ba2ddb82857c0591"
      },
      "status": "passed",
      "summary_sha256": "4d5b1401badd66f6b1c33040d7bbbcfbc68ac611c3a7f508cb29a57bc2d95594",
      "target": "latest"
    },
    {
      "cases": [
        "two_session_lock_cycle"
      ],
      "id": "runtime.40P01-manual-boundary-final-20260909.pg10",
      "image": "postgres@sha256:b2baf8998630663d21370da06387c950e587071bdd307ee34e661cdcc7442bcc",
      "limits": "This run proves the registry BEGIN/COMMIT/ROLLBACK statements for both lock-cycle sessions and the ordered retry execute with autocommit=True; worker synchronization still uses barriers and observed lock waits.",
      "observed": {
        "connections_autocommit": {
          "first": true,
          "retry": true,
          "second": true
        },
        "retry": {
          "rows": [
            [
              1,
              "retry-1"
            ],
            [
              2,
              "retry-2"
            ]
          ],
          "status": "IDLE"
        },
        "transaction_control": "Registry BEGIN/COMMIT/ROLLBACK statements run with autocommit=True; no driver implicit BEGIN participates."
      },
      "raw_sha256": "c2789c19f9106cf34a49fbfa791fbe0e23706f87e8d8a133abfb360165aa8ee1",
      "run_id": "40P01-manual-boundary-final-20260909",
      "server_version": "10.21 (Debian 10.21-1.pgdg90+1)",
      "server_version_num": 100021,
      "snippet_registry": {
        "sha256": "71a3377497dc2c1ba5b71c9ba81f71fc3cff975fcd245613ba2ddb82857c0591"
      },
      "status": "passed",
      "summary_sha256": "1aca5e77935f4066898c72332cb16f06c16f56ccd00414349f21a746d46f6ed8",
      "target": "pg10"
    }
  ]
}
