Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions docs/roadmaps/roadmap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17704,3 +17704,20 @@ roadmap:
labels:
- kind:code
notes: null
- id: PMAT-3226
github_issue: null
item_type: task
title: 'check_roadmap_completion_is_cited: lane scratch under .claude/worktrees is scanned as if it were the tree'
status: planned
priority: medium
assigned_to: null
created: 2026-09-14T14:10:24Z
updated: 2026-09-14T14:10:24Z
spec: null
acceptance_criteria: []
phases: []
subtasks: []
estimated_effort: null
labels:
- kind:code
notes: null
42 changes: 41 additions & 1 deletion scripts/check_roadmap_completion_is_cited.sh
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,24 @@ def tokens(*texts):
# where a work contract lives. The second arm is not redundant: the first,
# alone, gave a free pass to any pmat-schema file under docs/roadmaps/ that was
# not called roadmap*.yaml, which the case table caught as two red rows.
# `.claude/worktrees/` is agy's throwaway lane workspace: a full checkout,
# roadmap.yaml and all, created per lane and left behind when one dies. It is in
# `.git/info/exclude`, so nothing under it can ever reach the tree CI gates --
# but this guard's universe deliberately includes UNTRACKED files (that is the
# hole it was written to close), so it walked straight into them and counted a
# second copy of every entry. Measured on a clean branch after one review
# quorum: 1107 phantom "NEW unprovable claims" pointing at innocent rows.
# check_complexity_ratchet.sh:149 already prunes `*/.claude/worktrees/*`.
# Checked here rather than only in the walk so the `git ls-files` half of the
# universe is covered by the same rule.
SCRATCH_PREFIX = ".claude/worktrees/"

def is_scratch(rel):
return rel.replace(os.sep, "/").startswith(SCRATCH_PREFIX)

def is_candidate(rel):
if is_scratch(rel):
return False
d, fn = os.path.split(rel)
if not fn.lower().endswith(".yaml"):
return False
Expand All @@ -234,7 +251,13 @@ def is_candidate(rel):

cand = set()
for dirpath, dirnames, filenames in os.walk(root):
dirnames[:] = [d for d in dirnames if d not in (".git", "target", "node_modules")]
reldir = os.path.relpath(dirpath, root).replace(os.sep, "/")
dirnames[:] = [
d for d in dirnames
if d not in (".git", "target", "node_modules")
# do not descend into lane scratch: 66 worktrees were registered here
and (reldir + "/" + d).lstrip("./") != SCRATCH_PREFIX.rstrip("/")
]
for fn in filenames:
rel = os.path.relpath(os.path.join(dirpath, fn), root)
if is_candidate(rel):
Expand Down Expand Up @@ -580,6 +603,23 @@ YAML
row 'completed PHASE is gated' uncited "$(short "$(verdict_of 'phase:R-PHASE-PARENT/Phase one')")"
row 'duplicate id gets a positional key' uncited "$(short "$(verdict_of 'R-DUP [#2]')")"

# LANE SCRATCH. `.claude/worktrees/` is agy's throwaway lane workspace and is
# in `.git/info/exclude`, so nothing under it can ever reach the tree CI sees.
# It holds a full checkout, roadmap.yaml included. Walking into it counted a
# second copy of every entry: measured 1107 phantom "NEW unprovable claims" on
# a clean branch, a false RED that sends the reader to 1107 innocent rows.
# check_complexity_ratchet.sh already prunes `*/.claude/worktrees/*`; this
# guard never got the same fix.
mk .claude/worktrees/lane-deadbeef/docs/roadmaps/roadmap.yaml <<'YAML'
roadmap:
- id: R-LANE-SCRATCH
status: completed
notes: null
YAML
scan_roadmaps "$TD" >"$TD/scan3.out" 2>"$TD/scan3.err" || true
n_lane=$(grep -c 'lane-deadbeef' "$TD/scan3.out" "$TD/scan3.err" 2>/dev/null | awk -F: '{t+=$2} END {print t+0}')
row 'lane scratch contributes no records' 0 "$n_lane"

n_out=$(grep -c '^SCOPE out crates/other/roadmap.yaml' "$TD/scan.err" || true)
row 'foreign schema is reported out of scope, not skipped' 1 "$n_out"
n_rec=$(grep -c 'crates/other/roadmap.yaml' <<< "$SCAN" || true)
Expand Down
Loading