)]}'
{
  "commit": "6ff0ef97702c0e6b6d17b7a8fe856b31164efe57",
  "tree": "ae456b01bc223be69db574be753c191c92abb83a",
  "parents": [
    "03a329eeda09e073d7de9be84df55d65392e4013"
  ],
  "author": {
    "name": "hathach",
    "email": "thach@tinyusb.org",
    "time": "Fri Aug 21 23:14:25 2026 +0700"
  },
  "committer": {
    "name": "hathach",
    "email": "thach@tinyusb.org",
    "time": "Fri Aug 21 23:14:25 2026 +0700"
  },
  "message": "build_utils: key the caches on the tree, not just the arguments\n\nThe eight lru_cache layers take repo-RELATIVE paths - \u0027hw/bsp/\u003cfam\u003e\u0027,\n\u0027examples/\u003cex\u003e/skip.txt\u0027, the literal \u0027hw/bsp\u0027 glob - while ci_select._in_repo()\nchdirs around every call so one process can classify more than one tree. With no\ncwd in the key the second tree gets the first tree\u0027s answers.\n\nReproduced: skip_example(\u0027host/bare_api\u0027,\u0027metro_m0_express\u0027) is False at the repo\nroot and STILL False after chdir into a tree where that board does not exist; only\ncache_clear() gave the right answer. It bites the code-size skill\u0027s base-vs-branch\nworktree compare, /pre-pr, and the first test that points classify_build at a\nfixture tree. Master had no caching here, so the hazard arrived with it.\n\n_cwd_cache puts os.getcwd() in the key. The 199-test suite passed before only\nbecause every test happens to pass the real REPO; the new\nTestCachesAreKeyedOnTheTree crosses trees deliberately.\n\nAlso adds the drift guard the class rule was missing. Ports, hw/mcu, get_deps\ntokens and bsp families each have one; the class rule had only a comment claiming\nvendor_host.c was the sole \"enabled by no example config\" case until its removal -\nwhich src/class/bth falsifies today. TestClassesWithNoEnablingExample pins the set\nto {bth}, so a class added before its first example, or an example config flipped\nto 0, fails here instead of silently selecting nothing on both axes. Verified it\nfires by adding a class dir nothing enables.\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "66b20b2e41ad20024b1ef0fb8f306883be95384d",
      "old_mode": 33188,
      "old_path": "test/hil/test/test_ci_select.py",
      "new_id": "9b2c61ef2aaa25c1b72480cda7a467656de1054b",
      "new_mode": 33188,
      "new_path": "test/hil/test/test_ci_select.py"
    },
    {
      "type": "modify",
      "old_id": "1eeef026968fda77129be06a0ab21a7400b16b12",
      "old_mode": 33261,
      "old_path": "tools/build_utils.py",
      "new_id": "1b81335e00af93570dc175fc715c58ccaa353a33",
      "new_mode": 33261,
      "new_path": "tools/build_utils.py"
    }
  ]
}
