_apply_plan() fails to match target root directory from plan paths #76

Closed
opened 2026-04-12 20:37:24 -06:00 by claude-code · 0 comments
Collaborator

Root Cause Analysis

Symptom

When running luminos against luminos_lib/, the planning pass correctly identified it as a priority directory with suggested_turns: 20, but the dir loop received only 10 turns (the default). The plan's allocation was silently ignored.

Root cause

_apply_plan() builds a lookup table mapping relative paths to absolute paths:

rel_to_abs = {}
for d in all_dirs:
    rel = os.path.relpath(d, target)
    rel_to_abs[rel] = d

When d is the target directory itself, os.path.relpath(target, target) returns ".". So the lookup table has {".": "/abs/path/to/luminos_lib", ...}.

But the planner sees the directory tree rendered by render_tree(), which shows luminos_lib/ as the root label (using os.path.basename(target)). The planner naturally uses "luminos_lib" as the path in its plan output. The key "luminos_lib" doesn't exist in rel_to_abs (it's stored as "."), so the if rel in rel_to_abs check fails silently, and the directory falls through to the default tier.

Why it's silent

_apply_plan() deliberately ignores unknown paths in the plan (to handle planner hallucinations gracefully). This means a legitimate path mismatch looks identical to a hallucinated path. No warning is logged.

The . vs basename inconsistency

The codebase already knows about this: _build_dir_loop_context() normalizes "." to os.path.basename(target) for display purposes (ai.py:1035). The tree renderer uses basename(target) as the root label. But _apply_plan() doesn't apply this normalization in its lookup, creating a mismatch between what the planner sees and what the orchestrator expects.

Fix

In _apply_plan(), add the basename alias when the relative path is ".":

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

This makes both "." and "luminos_lib" resolve to the same absolute path. The planner can use either form and the match succeeds.

Also consider logging a warning when a plan path doesn't match any known directory, so future mismatches are visible rather than silent.

Impact

Any investigation where the target root directory appears in the plan (priority, shallow, or skip) will have its allocation silently ignored. This is most visible on small targets where the root is the most important directory.

Discovered in

Smoke test of Phase 3 (PR #75). Plan allocated 20 turns to luminos_lib, orchestrator gave it 10.

## Root Cause Analysis ### Symptom When running luminos against `luminos_lib/`, the planning pass correctly identified it as a priority directory with `suggested_turns: 20`, but the dir loop received only 10 turns (the default). The plan's allocation was silently ignored. ### Root cause `_apply_plan()` builds a lookup table mapping relative paths to absolute paths: ```python rel_to_abs = {} for d in all_dirs: rel = os.path.relpath(d, target) rel_to_abs[rel] = d ``` When `d` is the target directory itself, `os.path.relpath(target, target)` returns `"."`. So the lookup table has `{".": "/abs/path/to/luminos_lib", ...}`. But the planner sees the directory tree rendered by `render_tree()`, which shows `luminos_lib/` as the root label (using `os.path.basename(target)`). The planner naturally uses `"luminos_lib"` as the path in its plan output. The key `"luminos_lib"` doesn't exist in `rel_to_abs` (it's stored as `"."`), so the `if rel in rel_to_abs` check fails silently, and the directory falls through to the default tier. ### Why it's silent `_apply_plan()` deliberately ignores unknown paths in the plan (to handle planner hallucinations gracefully). This means a legitimate path mismatch looks identical to a hallucinated path. No warning is logged. ### The `.` vs basename inconsistency The codebase already knows about this: `_build_dir_loop_context()` normalizes `"."` to `os.path.basename(target)` for display purposes (`ai.py:1035`). The tree renderer uses `basename(target)` as the root label. But `_apply_plan()` doesn't apply this normalization in its lookup, creating a mismatch between what the planner sees and what the orchestrator expects. ### Fix In `_apply_plan()`, add the basename alias when the relative path is `"."`: ```python 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 ``` This makes both `"."` and `"luminos_lib"` resolve to the same absolute path. The planner can use either form and the match succeeds. Also consider logging a warning when a plan path doesn't match any known directory, so future mismatches are visible rather than silent. ### Impact Any investigation where the target root directory appears in the plan (priority, shallow, or skip) will have its allocation silently ignored. This is most visible on small targets where the root is the most important directory. ### Discovered in Smoke test of Phase 3 (PR #75). Plan allocated 20 turns to `luminos_lib`, orchestrator gave it 10.
claude-code added this to the Phase 3: Investigation Planning milestone 2026-04-12 20:37:24 -06:00
Sign in to join this conversation.
No labels
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: archeious/luminos#76
No description provided.