From 79bb10b9dc7dda1a8118dad99b8f0904c54f55fa Mon Sep 17 00:00:00 2001 From: Jeff Smith Date: Sun, 12 Apr 2026 20:38:55 -0600 Subject: [PATCH] fix(ai): match target root dir by basename in _apply_plan() (#76) The planner sees basename(target) in the tree output (e.g. "luminos_lib") and uses that as the path in its plan. But _apply_plan() mapped the target root to "." via os.path.relpath(), so the planner's path never matched and the allocation was silently dropped. Fix: register both "." and basename(target) as aliases for the target root in the lookup table. Also log a warning when plan paths don't match any known directory, so future mismatches are visible. Co-Authored-By: Claude Opus 4.6 (1M context) --- luminos_lib/ai.py | 19 +++++++++++++++++++ tests/test_ai_pure.py | 24 ++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/luminos_lib/ai.py b/luminos_lib/ai.py index 845b960..d3d569d 100644 --- a/luminos_lib/ai.py +++ b/luminos_lib/ai.py @@ -1549,21 +1549,29 @@ def _apply_plan(all_dirs, to_investigate, plan, target): return list(to_investigate), {} # Build lookup from relative path to absolute path. + # The target root maps to "." via relpath, but the planner sees + # basename(target) in the tree output and uses that as the path. + # Register both so either form matches (#76). rel_to_abs = {} for d in all_dirs: rel = os.path.relpath(d, target) rel_to_abs[rel] = d + if rel == ".": + rel_to_abs[os.path.basename(d)] = d # Classify directories by tier. skip_set = set() priority_set = set() shallow_set = set() turn_map = {} + unmatched = [] for entry in plan.get("skip_dirs", []): rel = entry.get("path", "") if rel in rel_to_abs: skip_set.add(rel_to_abs[rel]) + else: + unmatched.append(rel) for entry in plan.get("priority_dirs", []): rel = entry.get("path", "") @@ -1573,6 +1581,8 @@ def _apply_plan(all_dirs, to_investigate, plan, target): abs_path = rel_to_abs[rel] priority_set.add(abs_path) turn_map[abs_path] = capped + else: + unmatched.append(rel) for entry in plan.get("shallow_dirs", []): rel = entry.get("path", "") @@ -1580,6 +1590,15 @@ def _apply_plan(all_dirs, to_investigate, plan, target): abs_path = rel_to_abs[rel] shallow_set.add(abs_path) turn_map[abs_path] = _SHALLOW_TURNS + else: + unmatched.append(rel) + + if unmatched: + print( + f" [AI] Warning: plan referenced unknown dirs: " + f"{', '.join(unmatched)}", + file=sys.stderr, + ) # Remove skipped dirs from the investigation list. remaining = [d for d in to_investigate if d not in skip_set] diff --git a/tests/test_ai_pure.py b/tests/test_ai_pure.py index 7562afd..366efbe 100644 --- a/tests/test_ai_pure.py +++ b/tests/test_ai_pure.py @@ -878,6 +878,30 @@ class TestApplyPlan(unittest.TestCase): ) self.assertEqual(len(ordered), len(subset)) + def test_target_root_matched_by_basename(self): + """Plan can reference the target root by its basename, not just '.' (#76).""" + plan = _default_plan() + basename = os.path.basename(self.tmp) + plan["priority_dirs"] = [ + {"path": basename, "reason": "root is important", + "suggested_turns": 18}, + ] + _, turn_map = _apply_plan( + self.all_dirs, list(self.all_dirs), plan, self.target, + ) + self.assertEqual(turn_map[self.tmp], 18) + + def test_target_root_matched_by_dot(self): + """Plan can also reference the target root as '.'.""" + plan = _default_plan() + plan["priority_dirs"] = [ + {"path": ".", "reason": "root", "suggested_turns": 16}, + ] + _, turn_map = _apply_plan( + self.all_dirs, list(self.all_dirs), plan, self.target, + ) + self.assertEqual(turn_map[self.tmp], 16) + # --------------------------------------------------------------------------- # _get_child_summaries (updated placeholder behavior)