{
 "action": "Not for automatic application — after the patch the example still uses basic_constraints, which the verified example does not: the patch covers part of the change. Show this correction to the user as a lead. Rewrite the block as shown; the failing call does not appear in the new version of the block.",
 "alternatives": [
  {
   "action": "Not for automatic application — applied word for word, the patch does not parse: IndentationError: unexpected indent (line 26). Show this correction to the user as a lead. Replace the old line with the new one; the rest of the code can stay.",
   "applicability": {
    "line": 25,
    "method": "literal_patch",
    "occurrences": 1,
    "patched_sha": "7a943bd782f9",
    "reason": "applied word for word, the patch does not parse: IndentationError: unexpected indent (line 26)",
    "run_on": "26.4.0",
    "status": "syntax_error"
   },
   "by_notes": false,
   "changelog_ref": {
    "quote": "",
    "url": ""
   },
   "confirmations": 1,
   "detect": [
    "crypto.X509Extension"
   ],
   "equivalence": "same",
   "format": "replace",
   "kind": "changed",
   "right": "count = len(cert.extensions)",
   "script_right": "import datetime\nimport warnings\n\nfrom cryptography import x509\nfrom cryptography.hazmat.primitives import hashes\nfrom cryptography.x509.oid import NameOID\nfrom OpenSSL import crypto\n\n# X509Extension is deprecated in newer pyOpenSSL releases; silence the warnings\nwarnings.filterwarnings(\"ignore\", category=DeprecationWarning)\n\n\ndef main():\n    # Generate a 2048-bit RSA key\n    key = crypto.PKey()\n    key.generate_key(crypto.TYPE_RSA, 2048)\n    crypto_key = key.to_cryptography_key()\n\n    # Build the self-signed certificate\n    subject = x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, \"test.local\")])\n    now = datetime.datetime.now(datetime.timezone.utc)\n    builder = (\n        x509.CertificateBuilder()  # X.509 v3\n        .serial_number(1)\n        .subject_name(subject)\n        .issuer_name(subject)\n        .not_valid_before(now)\n        .not_valid_after(now + datetime.timedelta(seconds=365 * 24 * 60 * 60))\n        .public_key(crypto_key.public_key())\n    )\n\n    # Attach basicConstraints marking this certificate as a CA\n    builder = builder.add_extension(\n        x509.BasicConstraints(ca=True, path_length=None), critical=True\n    )\n\n    # Sign with the private key\n    cert = builder.sign(crypto_key, hashes.SHA256())\n\n    # Print extension count and each extension's short name and value\n    count = len(cert.extensions)\n    print(\"Extension count:\", count)\n    for i, ext in enumerate(cert.extensions):\n        short_name = ext.oid._name\n        value = ext.value\n        if isinstance(value, x509.BasicConstraints):\n            text = \"CA:TRUE\" if value.ca else \"CA:FALSE\"\n            if value.path_length is not None:\n                text += f\", pathlen:{value.path_length}\"\n        else:\n            text = str(value)\n        print(f\"Extension {i}: {short_name} = {text}\")\n\n\nif __name__ == \"__main__\":\n    main()",
   "script_wrong": "import warnings\n\nfrom OpenSSL import crypto\n\n# X509Extension is deprecated in newer pyOpenSSL releases; silence the warnings\nwarnings.filterwarnings(\"ignore\", category=DeprecationWarning)\n\n\ndef main():\n    # Generate a 2048-bit RSA key\n    key = crypto.PKey()\n    key.generate_key(crypto.TYPE_RSA, 2048)\n\n    # Build the self-signed certificate\n    cert = crypto.X509()\n    cert.set_version(2)  # X.509 v3\n    cert.set_serial_number(1)\n    cert.get_subject().CN = \"test.local\"\n    cert.set_issuer(cert.get_subject())\n    cert.gmtime_adj_notBefore(0)\n    cert.gmtime_adj_notAfter(365 * 24 * 60 * 60)\n    cert.set_pubkey(key)\n\n    # Attach basicConstraints marking this certificate as a CA\n    basic_constraints = crypto.X509Extension(\n        b\"basicConstraints\", True, b\"CA:TRUE\"\n    )\n    cert.add_extensions([basic_constraints])\n\n    # Sign with the private key\n    cert.sign(key, \"sha256\")\n\n    # Print extension count and each extension's short name and value\n    count = cert.get_extension_count()\n    print(\"Extension count:\", count)\n    for i in range(count):\n        ext = cert.get_extension(i)\n        short_name = ext.get_short_name()\n        if isinstance(short_name, bytes):\n            short_name = short_name.decode(\"ascii\", \"replace\")\n        print(f\"Extension {i}: {short_name} = {str(ext)}\")\n\n\nif __name__ == \"__main__\":\n    main()",
   "seen_in_models": [
    "claude-sonnet-5-5"
   ],
   "wrong": "basic_constraints = crypto.X509Extension("
  },
  {
   "action": "Not for automatic application — the patched example does not run on 26.4.0: exit code 1, NameError: name 'builder' is not defined. Show this correction to the user as a lead. Rewrite the block as shown; the failing call does not appear in the new version of the block.",
   "applicability": {
    "exit_code": 1,
    "line": 18,
    "method": "literal_patch",
    "occurrences": 1,
    "patched_sha": "e6e02b47dad0",
    "reason": "the patched example does not run on 26.4.0: exit code 1, NameError: name 'builder' is not defined",
    "run_on": "26.4.0",
    "status": "fails"
   },
   "by_notes": false,
   "changelog_ref": {
    "quote": "",
    "url": ""
   },
   "confirmations": 1,
   "detect": [
    "crypto.X509Extension"
   ],
   "equivalence": "same",
   "format": "fragment",
   "kind": "changed",
   "right": "builder = builder.add_extension(\nx509.BasicConstraints(ca=True, path_length=None), critical=True\n)",
   "script_right": "import datetime\n\nfrom OpenSSL import crypto\nfrom cryptography import x509\nfrom cryptography.hazmat.primitives import hashes\nfrom cryptography.x509.oid import NameOID\n\n# Generate a 2048-bit RSA key\nkey = crypto.PKey()\nkey.generate_key(crypto.TYPE_RSA, 2048)\ncrypto_key = key.to_cryptography_key()\n\n# Create a self-signed certificate\nsubject = x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, \"test.local\")])\nnow = datetime.datetime.now(datetime.timezone.utc)\nbuilder = (\n    x509.CertificateBuilder()  # X.509 v3\n    .subject_name(subject)\n    .serial_number(1000)\n    .not_valid_before(now)\n    .not_valid_after(now + datetime.timedelta(seconds=365 * 24 * 60 * 60))\n    .issuer_name(subject)\n    .public_key(crypto_key.public_key())\n)\n\n# Attach basicConstraints extension marking it as a CA\nbuilder = builder.add_extension(\n    x509.BasicConstraints(ca=True, path_length=None), critical=True\n)\n\n# Sign the certificate with the private key\ncert = crypto.X509.from_cryptography(builder.sign(crypto_key, hashes.SHA256()))\n\n\ndef _ext_value(extension):\n    value = extension.value\n    if isinstance(value, x509.BasicConstraints):\n        text = \"CA:TRUE\" if value.ca else \"CA:FALSE\"\n        if value.path_length is not None:\n            text += f\", pathlen:{value.path_length}\"\n        return text\n    return str(value)\n\n\n# Print the extension count and each extension's short name and value\nextensions = cert.to_cryptography().extensions\ncount = len(extensions)\nprint(f\"Extension count: {count}\")\n\nfor i in range(count):\n    extension = extensions[i]\n    short_name = extension.oid._name\n    value = _ext_value(extension)\n    print(f\"{short_name}: {value}\")",
   "script_wrong": "from OpenSSL import crypto\n\n# Generate a 2048-bit RSA key\nkey = crypto.PKey()\nkey.generate_key(crypto.TYPE_RSA, 2048)\n\n# Create a self-signed certificate\ncert = crypto.X509()\ncert.set_version(2)  # X.509 v3\ncert.get_subject().CN = \"test.local\"\ncert.set_serial_number(1000)\ncert.gmtime_adj_notBefore(0)\ncert.gmtime_adj_notAfter(365 * 24 * 60 * 60)\ncert.set_issuer(cert.get_subject())\ncert.set_pubkey(key)\n\n# Attach basicConstraints extension marking it as a CA\next = crypto.X509Extension(b\"basicConstraints\", True, b\"CA:TRUE\")\ncert.add_extensions([ext])\n\n# Sign the certificate with the private key\ncert.sign(key, \"sha256\")\n\n# Print the extension count and each extension's short name and value\ncount = cert.get_extension_count()\nprint(f\"Extension count: {count}\")\n\nfor i in range(count):\n    extension = cert.get_extension(i)\n    short_name = extension.get_short_name().decode(\"utf-8\", errors=\"replace\")\n    value = str(extension)\n    print(f\"{short_name}: {value}\")",
   "seen_in_models": [
    "gemini-3.8-flash"
   ],
   "wrong": "ext = crypto.X509Extension(b\"basicConstraints\", True, b\"CA:TRUE\")\ncert.add_extensions([ext])"
  },
  {
   "action": "Not for automatic application — the patched example does not run on 26.4.0: exit code 1, UnboundLocalError: cannot access local variable 'builder' where it is not associated with a value. Show this correction to the user as a lead. Rewrite the block as shown; the failing call does not appear in the new version of the block.",
   "applicability": {
    "exit_code": 1,
    "line": 27,
    "method": "literal_patch",
    "occurrences": 1,
    "patched_sha": "e1e52270a328",
    "reason": "the patched example does not run on 26.4.0: exit code 1, UnboundLocalError: cannot access local variable 'builder' where it is not associated with a value",
    "run_on": "26.4.0",
    "status": "fails"
   },
   "by_notes": true,
   "changelog_ref": {
    "quote": "Removed deprecated ``OpenSSL.crypto.X509Extension``, ``OpenSSL.crypto.X509Req.add_extension``, ``OpenSSL.crypto.X509Req.get_extensions``, ``OpenSSL.crypto.X509.add_extension``, ``OpenSSL.crypto.X509.get_extensions``. ``cryptography.x509`` should be used instead.",
    "url": "https://github.com/pyca/pyopenssl/blob/HEAD/CHANGELOG.rst"
   },
   "confirmations": 1,
   "detect": [
    "crypto.X509Extension"
   ],
   "equivalence": "same",
   "format": "fragment",
   "kind": "removed",
   "right": "builder = builder.add_extension(\nx509.BasicConstraints(ca=False, path_length=None), critical=True\n)",
   "script_right": "import datetime\nimport os\nimport warnings\n\nfrom cryptography import x509\nfrom cryptography.hazmat.primitives import hashes\nfrom cryptography.x509.oid import NameOID\nfrom OpenSSL import crypto\n\n# X509Extension is deprecated in recent pyOpenSSL releases but still works;\n# silence the warning so the output stays clean.\nwarnings.filterwarnings(\"ignore\", category=DeprecationWarning)\n\n\ndef main():\n    # Generate 2048-bit RSA key\n    key = crypto.PKey()\n    key.generate_key(crypto.TYPE_RSA, 2048)\n    ckey = key.to_cryptography_key()\n\n    # Build self-signed certificate (X.509 v3)\n    subject = x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, \"test.local\")])\n    now = datetime.datetime.now(datetime.timezone.utc)\n    builder = (\n        x509.CertificateBuilder()\n        .subject_name(subject)\n        .issuer_name(subject)\n        .serial_number(int.from_bytes(os.urandom(8), \"big\") >> 1)\n        .not_valid_before(now)\n        .not_valid_after(now + datetime.timedelta(seconds=365 * 24 * 60 * 60))\n        .public_key(ckey.public_key())\n    )\n\n    # Critical basicConstraints: CA:FALSE\n    builder = builder.add_extension(\n        x509.BasicConstraints(ca=False, path_length=None), critical=True\n    )\n\n    ccert = builder.sign(ckey, hashes.SHA256())\n    cert = crypto.X509.from_cryptography(ccert)\n\n    # Print subject CN\n    print(\"Subject CN:\", cert.get_subject().CN)\n\n    # Print each extension's short name and value\n    for ext in ccert.extensions:\n        name = ext.oid._name\n        value = ext.value\n        if isinstance(value, x509.BasicConstraints):\n            text = \"CA:TRUE\" if value.ca else \"CA:FALSE\"\n            if value.path_length is not None:\n                text += f\", pathlen:{value.path_length}\"\n        else:\n            text = str(value)\n        print(f\"{name}: {text} (critical={bool(ext.critical)})\")\n\n\nif __name__ == \"__main__\":\n    main()",
   "script_wrong": "import warnings\n\nfrom OpenSSL import crypto\n\n# X509Extension is deprecated in recent pyOpenSSL releases but still works;\n# silence the warning so the output stays clean.\nwarnings.filterwarnings(\"ignore\", category=DeprecationWarning)\n\n\ndef main():\n    # Generate 2048-bit RSA key\n    key = crypto.PKey()\n    key.generate_key(crypto.TYPE_RSA, 2048)\n\n    # Build self-signed certificate\n    cert = crypto.X509()\n    cert.set_version(2)  # X.509 v3\n    cert.set_serial_number(int.from_bytes(__import__(\"os\").urandom(8), \"big\") >> 1)\n    subject = cert.get_subject()\n    subject.CN = \"test.local\"\n    cert.set_issuer(subject)\n    cert.gmtime_adj_notBefore(0)\n    cert.gmtime_adj_notAfter(365 * 24 * 60 * 60)\n    cert.set_pubkey(key)\n\n    # Critical basicConstraints: CA:FALSE\n    bc = crypto.X509Extension(b\"basicConstraints\", True, b\"CA:FALSE\")\n    cert.add_extensions([bc])\n\n    cert.sign(key, \"sha256\")\n\n    # Print subject CN\n    print(\"Subject CN:\", cert.get_subject().CN)\n\n    # Print each extension's short name and value\n    for i in range(cert.get_extension_count()):\n        ext = cert.get_extension(i)\n        name = ext.get_short_name().decode(\"ascii\")\n        print(f\"{name}: {str(ext)} (critical={bool(ext.get_critical())})\")\n\n\nif __name__ == \"__main__\":\n    main()",
   "seen_in_models": [
    "claude-sonnet-5-5"
   ],
   "wrong": "bc = crypto.X509Extension(b\"basicConstraints\", True, b\"CA:FALSE\")\ncert.add_extensions([bc])"
  }
 ],
 "applicability": {
  "leftover": [
   "basic_constraints"
  ],
  "line": 26,
  "method": "literal_patch",
  "occurrences": 1,
  "patched_sha": "2c743497bee1",
  "reason": "after the patch the example still uses basic_constraints, which the verified example does not: the patch covers part of the change",
  "run_on": "26.4.0",
  "status": "incomplete"
 },
 "by_notes": false,
 "changelog_ref": {
  "quote": "",
  "url": ""
 },
 "confirmations": {
  "failed": 0,
  "worked": 8
 },
 "detect": [
  "crypto.X509Extension"
 ],
 "ecosystem": "pypi",
 "equivalence": "same",
 "error_kind": "missing_attr",
 "error_signature": {
  "message": "module 'OpenSSL.crypto' has no attribute 'X509Extension'",
  "norm": "missing_attr:x509extension",
  "type": "AttributeError"
 },
 "first_seen": "2026-10-23T05:42:51+00:00",
 "format": "fragment",
 "format_version": 2,
 "id": "pypi/pyopenssl/26.4.0/0002",
 "kind": "changed",
 "license": "https://creativecommons.org/licenses/by/4.0/",
 "package": "pyopenssl",
 "proof": {
  "applicability": {
   "leftover": [
    "basic_constraints"
   ],
   "line": 26,
   "method": "literal_patch",
   "occurrences": 1,
   "patched_sha": "2c743497bee1",
   "reason": "after the patch the example still uses basic_constraints, which the verified example does not: the patch covers part of the change",
   "run_on": "26.4.0",
   "status": "incomplete"
  },
  "auto_apply": false,
  "auto_apply_reason": "the patch gives incomplete when applied word for word",
  "auto_apply_rule": "Automatic application is allowed only when proof.equivalent is true and proof.applicability.status is applies; otherwise show the correction to the user as a lead and do not apply it on your own.",
  "equivalence": "same",
  "equivalent": true,
  "fails_on": "26.4.0",
  "fixed_on": "26.4.0",
  "level": "differential",
  "method": {
   "fix_on": "26.4.0",
   "name": "stdout_match",
   "normalization": "lines stripped, blank lines dropped, runs of whitespace collapsed; memory addresses, timestamps and temporary paths masked",
   "original_on": "26.0.0",
   "scope": "the observable stdout of one example script; return values, files, other inputs and exception types are not compared, so a match is not a proof of equivalent behaviour"
  },
  "script_right": "import datetime\nimport warnings\n\nfrom cryptography import x509\nfrom cryptography.hazmat.primitives import hashes\nfrom cryptography.x509.oid import NameOID\nfrom OpenSSL import crypto\n\n# X509Extension is flagged as deprecated in newer pyOpenSSL releases, but it is\n# still the pyOpenSSL-native way to add extensions. Suppress the warning noise.\nwarnings.filterwarnings(\"ignore\", category=DeprecationWarning)\n\n\ndef _ext_value_str(ext):\n    value = ext.value\n    if isinstance(value, x509.BasicConstraints):\n        s = \"CA:TRUE\" if value.ca else \"CA:FALSE\"\n        if value.path_length is not None:\n            s += f\", pathlen:{value.path_length}\"\n        return s\n    return str(value)\n\n\ndef main():\n    # Generate a 2048-bit RSA key\n    key = crypto.PKey()\n    key.generate_key(crypto.TYPE_RSA, 2048)\n    crypto_key = key.to_cryptography_key()\n\n    # Build the certificate\n    subject = x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, \"test.local\")])\n    now = datetime.datetime.now(datetime.timezone.utc)\n    builder = (\n        x509.CertificateBuilder()  # X.509 v3\n        .serial_number(1000)\n        .subject_name(subject)\n        .issuer_name(subject)  # self-signed\n        .not_valid_before(now)\n        .not_valid_after(now + datetime.timedelta(seconds=365 * 24 * 60 * 60))\n        .public_key(crypto_key.public_key())\n    )\n\n    # Attach basicConstraints extension marking the cert as a CA\n    builder = builder.add_extension(\n        x509.BasicConstraints(ca=True, path_length=None), critical=True\n    )\n\n    # Self-sign\n    cert = builder.sign(crypto_key, hashes.SHA256())\n\n    # Print extension info\n    extensions = list(cert.extensions)\n    count = len(extensions)\n    print(\"Extension count:\", count)\n    for i in range(count):\n        ext = extensions[i]\n        short_name = ext.oid._name\n        if isinstance(short_name, bytes):\n            short_name = short_name.decode(\"ascii\")\n        print(f\"Extension {i}: {short_name} = {_ext_value_str(ext)}\")\n\n\nif __name__ == \"__main__\":\n    main()",
  "script_wrong": "import warnings\n\nfrom OpenSSL import crypto\n\n# X509Extension is flagged as deprecated in newer pyOpenSSL releases, but it is\n# still the pyOpenSSL-native way to add extensions. Suppress the warning noise.\nwarnings.filterwarnings(\"ignore\", category=DeprecationWarning)\n\n\ndef main():\n    # Generate a 2048-bit RSA key\n    key = crypto.PKey()\n    key.generate_key(crypto.TYPE_RSA, 2048)\n\n    # Build the certificate\n    cert = crypto.X509()\n    cert.set_version(2)  # X.509 v3\n    cert.set_serial_number(1000)\n    cert.get_subject().CN = \"test.local\"\n    cert.set_issuer(cert.get_subject())  # self-signed\n    cert.gmtime_adj_notBefore(0)\n    cert.gmtime_adj_notAfter(365 * 24 * 60 * 60)\n    cert.set_pubkey(key)\n\n    # Attach basicConstraints extension marking the cert as a CA\n    basic_constraints = crypto.X509Extension(\n        b\"basicConstraints\", True, b\"CA:TRUE\"\n    )\n    cert.add_extensions([basic_constraints])\n\n    # Self-sign\n    cert.sign(key, \"sha256\")\n\n    # Print extension info\n    count = cert.get_extension_count()\n    print(\"Extension count:\", count)\n    for i in range(count):\n        ext = cert.get_extension(i)\n        short_name = ext.get_short_name()\n        if isinstance(short_name, bytes):\n            short_name = short_name.decode(\"ascii\")\n        print(f\"Extension {i}: {short_name} = {str(ext)}\")\n\n\nif __name__ == \"__main__\":\n    main()",
  "works_on": "26.0.0"
 },
 "right": "builder = builder.add_extension(\nx509.BasicConstraints(ca=True, path_length=None), critical=True",
 "seen_in_models": [
  "claude-sonnet-5-5",
  "gemini-3.8-flash"
 ],
 "seq": 2,
 "slug": "openssl-crypto-x509extension",
 "source": "pipeline",
 "symbol": "X509Extension",
 "updated": "2026-10-27T17:20:00+00:00",
 "url": "https://formachines.ai/errata/pypi/pyopenssl/0002-openssl-crypto-x509extension/",
 "variant_confirmations": 4,
 "variant_models": [
  "claude-sonnet-5-5",
  "gemini-3.8-flash"
 ],
 "verified": "sandbox",
 "versions": {
  "changed_in": ">26.0.0,<=26.4.0",
  "fails_on": "26.4.0",
  "works_on": "26.0.0"
 },
 "wrong": "basic_constraints = crypto.X509Extension(\nb\"basicConstraints\", True, b\"CA:TRUE\""
}