)]}'
{
  "commit": "72c94871c7cc3dbc111b1b29dedf3b982a93827d",
  "tree": "85fb8063407926a92629b8db78931f832fde4fac",
  "parents": [
    "1627fbad040afec97a68bc147104081abac16408"
  ],
  "author": {
    "name": "Jarek Potiuk",
    "email": "jarek@potiuk.com",
    "time": "Sun May 31 15:26:19 2026 +0200"
  },
  "committer": {
    "name": "Jarek Potiuk",
    "email": "jarek@potiuk.com",
    "time": "Sun May 31 15:26:19 2026 +0200"
  },
  "message": "Add security and project harness\n\nAdds local and CI tooling to keep the repo ASF-compliant and secure:\n\n- prek (.pre-commit-config.yaml) with pre-commit / commit-msg / pre-push\n  hooks: license-header insertion, trailing-whitespace/EOF/YAML/JSON checks,\n  workflow + dependabot schema validation, a commit-msg hook that rejects\n  Co-authored-by trailers, and a pre-push suite (tests, license allowlist,\n  zizmor).\n- Apache-2.0 license headers on all source files (js/py/sh/html), placed\n  after shebangs and PEP-723 metadata blocks.\n- Dependency license allowlist check (scripts/check-licenses.mjs) gating npm\n  dependencies to ASF Category-A licenses; wired into CI and pre-push.\n- Track package-lock.json files (un-ignored) for reproducible \"npm ci\".\n- Dependabot coverage for mcp/apache-projects-mcp (cooldowns, like the others).\n- Consolidate MCP CI into mcp-tests.yml (matrix over both servers x Node\n  20/22, runs tests + license check); add static-checks.yml running prek.\n- AGENTS.md documenting setup, the pre-push checks, and the ASF attribution\n  policy (Generated-by, never Co-authored-by).\n\nGenerated-by: Claude Code 2.1.158 (Claude Opus 4.8)\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "998e2b00f49ff154233a11f0516f4cf70befc3cb",
      "old_mode": 33188,
      "old_path": ".github/dependabot.yml",
      "new_id": "75be55dc6a4d01f8c8f60cd69fc36adfbb75676f",
      "new_mode": 33188,
      "new_path": ".github/dependabot.yml"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "60b675e31016189b951f76d0bf9f668f32a1fb30",
      "new_mode": 33188,
      "new_path": ".github/license-header.txt"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "f106cccb82ba5141e803c3176ec922c2463cd207",
      "new_mode": 33188,
      "new_path": ".github/workflows/mcp-tests.yml"
    },
    {
      "type": "delete",
      "old_id": "dbac030d35f3164cef2474191a84cc2e955760bc",
      "old_mode": 33188,
      "old_path": ".github/workflows/ponymail-mcp-tests.yml",
      "new_id": "0000000000000000000000000000000000000000",
      "new_mode": 0,
      "new_path": "/dev/null"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "3edfa608d79d7ed314004ed861254adc5a65e312",
      "new_mode": 33188,
      "new_path": ".github/workflows/static-checks.yml"
    },
    {
      "type": "modify",
      "old_id": "2af3644af09a82f29154258e1a4540b97b3af664",
      "old_mode": 33188,
      "old_path": ".gitignore",
      "new_id": "316db7115677de480e01443bfddb14b9da1f4218",
      "new_mode": 33188,
      "new_path": ".gitignore"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "85495aebaca80739741fb88cfae46f8efa37b1fe",
      "new_mode": 33188,
      "new_path": ".pre-commit-config.yaml"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "32036838d546a58de01915607dab77e03a0cb581",
      "new_mode": 33188,
      "new_path": "AGENTS.md"
    },
    {
      "type": "modify",
      "old_id": "5fee5d5e11f65ec7733312bd7d6a22c0ae33c38d",
      "old_mode": 33188,
      "old_path": "README.md",
      "new_id": "8c1d55019a6c52f6e66cd3d08dc41e74159cd169",
      "new_mode": 33188,
      "new_path": "README.md"
    },
    {
      "type": "modify",
      "old_id": "41014362a90cea4940222c5bc08e330ce0942e94",
      "old_mode": 33261,
      "old_path": "asf-highlights/asf_activity.py",
      "new_id": "952e0b0a0523a91e998b1cf1a62fbf5d7a44d704",
      "new_mode": 33261,
      "new_path": "asf-highlights/asf_activity.py"
    },
    {
      "type": "modify",
      "old_id": "4a447a7e5d89bb0b02b29383b0e9b371e876311f",
      "old_mode": 33261,
      "old_path": "asf-highlights/project_birthdays.py",
      "new_id": "d317ebea0895f3a9421a9b7def0b28e8bf85a69a",
      "new_mode": 33261,
      "new_path": "asf-highlights/project_birthdays.py"
    },
    {
      "type": "modify",
      "old_id": "b91aa2d77182132475293bafcfa5adf071458169",
      "old_mode": 33188,
      "old_path": "mcp/apache-projects-mcp/README.md",
      "new_id": "aabca73a415b3a42320efdcc60d1a3f129cc5771",
      "new_mode": 33188,
      "new_path": "mcp/apache-projects-mcp/README.md"
    },
    {
      "type": "modify",
      "old_id": "883e61e0acc89447634fc5d35579d2e8ed35b8af",
      "old_mode": 33188,
      "old_path": "mcp/apache-projects-mcp/index.js",
      "new_id": "6b9f4325884d10b28fed86ba044fdeb7d8607d30",
      "new_mode": 33188,
      "new_path": "mcp/apache-projects-mcp/index.js"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "08c5639c740aaadc5ae4d53f1979e573348151dc",
      "new_mode": 33188,
      "new_path": "mcp/apache-projects-mcp/package-lock.json"
    },
    {
      "type": "modify",
      "old_id": "1ca3a8a6a931055aa4b2c3c9dbdfcceb183752cb",
      "old_mode": 33188,
      "old_path": "mcp/apache-projects-mcp/package.json",
      "new_id": "9c987ac6f939942984d9961b5b635f1a44fefdef",
      "new_mode": 33188,
      "new_path": "mcp/apache-projects-mcp/package.json"
    },
    {
      "type": "modify",
      "old_id": "56db4c973e94c8ddac6d9355c0fe43dceb0c1fbc",
      "old_mode": 33188,
      "old_path": "mcp/apache-projects-mcp/test/response.test.js",
      "new_id": "2c469cb59bfd6c9e88cd465a211cbc5c1e17d299",
      "new_mode": 33188,
      "new_path": "mcp/apache-projects-mcp/test/response.test.js"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "c2658d7d1b31848c3b71960543cb0368e56cd4c7",
      "new_mode": 33188,
      "new_path": "mcp/ponymail-mcp/.gitignore"
    },
    {
      "type": "modify",
      "old_id": "5e7c0172d847cadd97c3550daae13c6adc9b89f2",
      "old_mode": 33188,
      "old_path": "mcp/ponymail-mcp/auth.js",
      "new_id": "1467c73f2f365ec612082f1909d5d0dd47cc2a87",
      "new_mode": 33188,
      "new_path": "mcp/ponymail-mcp/auth.js"
    },
    {
      "type": "modify",
      "old_id": "0a067d92c6869e0917be0e1e2c6be6a34fdca2e6",
      "old_mode": 33188,
      "old_path": "mcp/ponymail-mcp/auth.test.js",
      "new_id": "af38aee089f558c26fe42281215555532572a4dc",
      "new_mode": 33188,
      "new_path": "mcp/ponymail-mcp/auth.test.js"
    },
    {
      "type": "modify",
      "old_id": "57b150d269ed743d2d3a36a4be15b7297e926979",
      "old_mode": 33188,
      "old_path": "mcp/ponymail-mcp/bookmarklet.html",
      "new_id": "c21cad75818309ee9e6266e1747ccfce826beb6c",
      "new_mode": 33188,
      "new_path": "mcp/ponymail-mcp/bookmarklet.html"
    },
    {
      "type": "modify",
      "old_id": "33d273a0d89c0554a20c7c49bc503427e6d94d62",
      "old_mode": 33188,
      "old_path": "mcp/ponymail-mcp/cookie-extract.js",
      "new_id": "4bbff37cd1b94243d6b28cb393dbd686c05b4dcf",
      "new_mode": 33188,
      "new_path": "mcp/ponymail-mcp/cookie-extract.js"
    },
    {
      "type": "modify",
      "old_id": "283bac36b79537d59cd596341c2bb68c9ff4707c",
      "old_mode": 33188,
      "old_path": "mcp/ponymail-mcp/cookie-extract.test.js",
      "new_id": "fcaa6c28bac8b978a382dd00724e50aaad625af9",
      "new_mode": 33188,
      "new_path": "mcp/ponymail-mcp/cookie-extract.test.js"
    },
    {
      "type": "modify",
      "old_id": "4a75ab8dd18b66636306af126e12cf61bea3e597",
      "old_mode": 33188,
      "old_path": "mcp/ponymail-mcp/index.js",
      "new_id": "acb4a788917b0cb8a3d17f44a05110afec762305",
      "new_mode": 33188,
      "new_path": "mcp/ponymail-mcp/index.js"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "eb00553b87261479c7c7291e738b8660c264583b",
      "new_mode": 33188,
      "new_path": "mcp/ponymail-mcp/package-lock.json"
    },
    {
      "type": "modify",
      "old_id": "2c0221b053a5e1a15632c86d4e964acf7e82362a",
      "old_mode": 33188,
      "old_path": "mcp/ponymail-mcp/package.json",
      "new_id": "6480ef919ca352e452d39a4563fdfbb2a2059955",
      "new_mode": 33188,
      "new_path": "mcp/ponymail-mcp/package.json"
    },
    {
      "type": "modify",
      "old_id": "eca1be32cf4b0f15929b241f2d2b5b753b679d18",
      "old_mode": 33188,
      "old_path": "mcp/ponymail-mcp/restrictions.js",
      "new_id": "114658249f66bac66689b493d9f555e4dd023b6e",
      "new_mode": 33188,
      "new_path": "mcp/ponymail-mcp/restrictions.js"
    },
    {
      "type": "modify",
      "old_id": "a472de94194507e935fdf3728f0fda2be204108c",
      "old_mode": 33188,
      "old_path": "mcp/ponymail-mcp/restrictions.test.js",
      "new_id": "1cdc5a708cb5a9ec866a1eafc87c6dde4a486ec9",
      "new_mode": 33188,
      "new_path": "mcp/ponymail-mcp/restrictions.test.js"
    },
    {
      "type": "modify",
      "old_id": "205b55a175d551f21b6e42dab81c0cdfdfe2be3a",
      "old_mode": 33261,
      "old_path": "project-activity/project_activity.py",
      "new_id": "feeea534ca17d3f32929195a844a31cd77615908",
      "new_mode": 33261,
      "new_path": "project-activity/project_activity.py"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "fdad200b50f62ec485eff56ec3ca5a2fc6847bf3",
      "new_mode": 33188,
      "new_path": "scripts/check-licenses.mjs"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "f7be8bdd44ae0b1c783544dd04609697cae7ead8",
      "new_mode": 33261,
      "new_path": "scripts/check-no-coauthor.sh"
    }
  ]
}
