)]}'
{
  "commit": "e939dde6c0c33cbc65706177846ff9f36f40544f",
  "tree": "7f947ec4171bd32f5f27ddd6250bff64d0b6a7fc",
  "parents": [
    "870f676e23b114bd6a1d09af6698b9548b3fa4c5"
  ],
  "author": {
    "name": "Jarek Potiuk",
    "email": "jarek@potiuk.com",
    "time": "Sat Apr 25 13:05:03 2026 +0200"
  },
  "committer": {
    "name": "Jarek Potiuk",
    "email": "jarek@potiuk.com",
    "time": "Sat Apr 25 13:05:03 2026 +0200"
  },
  "message": "Block all private lists by default, add opt-in allowlist\n\nPreviously the restriction layer relied solely on a fixed pattern list,\nso any unconventionally-named private list (e.g. names other than\nprivate@/security@) could slip through. This adds a second layer that\nchecks PonyMail\u0027s `private` flag on every response and blocks unless\nthe list is explicitly opted in via PONYMAIL_ALLOWED_LISTS.\n\n- restrictions.js: parse PONYMAIL_ALLOWED_LISTS, add allowedFor(),\n  isPrivateBlocked(), privateError(), listAllowed(). Module-load\n  capture is documented inline.\n- index.js: post-fetch private-flag check in search_list (including\n  per-email cross-listing scan), get_email, get_thread; pre-flight\n  stats probe in get_mbox (mbox returns raw text). list_lists flags\n  allow-listed lists; list_restrictions surfaces the policy plus\n  current allow-list. Fixes the dead `quick\u003d\"\"` parameter (filtered\n  by apiFetch) by sending `quick\u003d\"1\"`.\n- restrictions.test.js: 18 unit tests covering pattern grammar,\n  allowlist bypass, env-var parsing edge cases, isPrivateBlocked\n  truthy/falsy handling, and falsy-input tolerance. `npm test` runs\n  with the built-in node:test runner — no new dependencies.\n- README: documents the two-layer model, opt-in mechanism, the\n  PII / interim ASF policy considerations (with links to the ASF\n  Mailing Lists page and Privacy Policy), and Apache Airflow /\n  Apache Arrow security@ as opt-in examples.\n\nGenerated-by: Claude Code (Claude Opus 4.7)\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "13280feba7cf2e93366ab8684bec98244117086f",
      "old_mode": 33188,
      "old_path": "mcp/ponymail-mcp/README.md",
      "new_id": "41963a1dc1c184bf701c7f5c5d269bc87515647d",
      "new_mode": 33188,
      "new_path": "mcp/ponymail-mcp/README.md"
    },
    {
      "type": "modify",
      "old_id": "cde5972889fe21ec1090f34ed4dc3062abeced39",
      "old_mode": 33188,
      "old_path": "mcp/ponymail-mcp/index.js",
      "new_id": "d26d870205edf8ec8cfc39ca0a3c0e22259abd95",
      "new_mode": 33188,
      "new_path": "mcp/ponymail-mcp/index.js"
    },
    {
      "type": "modify",
      "old_id": "5a13754aa91ab1791694984a0b0c7c5fd4a193ab",
      "old_mode": 33188,
      "old_path": "mcp/ponymail-mcp/package.json",
      "new_id": "19a9ba3349244aa0f10c857a61ad0945404a022c",
      "new_mode": 33188,
      "new_path": "mcp/ponymail-mcp/package.json"
    },
    {
      "type": "modify",
      "old_id": "0b881f97a9491275a5cef2cf61f82ee80f00b145",
      "old_mode": 33188,
      "old_path": "mcp/ponymail-mcp/restrictions.js",
      "new_id": "eca1be32cf4b0f15929b241f2d2b5b753b679d18",
      "new_mode": 33188,
      "new_path": "mcp/ponymail-mcp/restrictions.js"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "542be1c08bd7ae5d97a3a405172ca8b115c2eba9",
      "new_mode": 33188,
      "new_path": "mcp/ponymail-mcp/restrictions.test.js"
    }
  ]
}
