From bf82aa2b881921454577c4b153bc13d89f492e6d Mon Sep 17 00:00:00 2001 From: carlos-alm Date: Mon, 6 Jul 2026 06:11:06 -0600 Subject: [PATCH 1/2] fix: update titan-grind's dead-symbol script for current roles --json object shape codegraph roles --role dead --json has always returned { count, summary, symbols } (never a bare array, confirmed back to the command's original commit) but three Node one-liners in titan-grind's SKILL.md assumed a bare array, calling .length/.reduce()/.filter() directly on the parsed JSON. Steps 0.12 and 4 threw "items.reduce is not a function"; the Step 2c symbol-level duplicate scan silently swallowed the same TypeError in a try/catch and always emitted an empty candidate list. Read .count and .summary directly (summary is already the per-role breakdown) and read .symbols for the duplicate-scan candidate list. Fixes #1762 --- .claude/skills/titan-grind/SKILL.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.claude/skills/titan-grind/SKILL.md b/.claude/skills/titan-grind/SKILL.md index 56e79513b..f6605c53e 100644 --- a/.claude/skills/titan-grind/SKILL.md +++ b/.claude/skills/titan-grind/SKILL.md @@ -109,8 +109,9 @@ Forge shapes the metal. Grind smooths the rough edges. Your goal: find helpers t 12. **Capture dead-symbol baseline** (only if `grind.deadSymbolBaseline` is null): ```bash - codegraph roles --role dead -T --json | node -e "const d=[];process.stdin.on('data',c=>d.push(c));process.stdin.on('end',()=>{const items=JSON.parse(Buffer.concat(d));console.log(JSON.stringify({total:items.length,byRole:items.reduce((a,i)=>{a[i.role]=(a[i.role]||0)+1;return a},{})}));})" + codegraph roles --role dead -T --json | node -e "const d=[];process.stdin.on('data',c=>d.push(c));process.stdin.on('end',()=>{const data=JSON.parse(Buffer.concat(d));console.log(JSON.stringify({total:data.count,byRole:data.summary}));})" ``` + `codegraph roles --json` returns `{ count, summary, symbols }` (not a bare array) — `summary` is already the per-role breakdown (e.g. `dead-leaf`, `dead-entry`, `dead-ffi`, `dead-unresolved`), so no manual reduce is needed. Store the total in `grind.deadSymbolBaseline`. Write `titan-state.json` immediately. 13. **Drift detection.** Compare `titan-state.json → mainSHA` against current origin/main: @@ -304,8 +305,8 @@ const tokens = helperName .slice(0, 3); const d=[];process.stdin.on('data',c=>d.push(c)); process.stdin.on('end',()=>{ try { - const items=JSON.parse(Buffer.concat(d)); - const candidates = items.filter(i => + const data=JSON.parse(Buffer.concat(d)); + const candidates = (data.symbols || []).filter(i => i.name !== helperName && tokens.some(t => i.name.toLowerCase().includes(t)) ); @@ -579,7 +580,7 @@ After all targets in the phase are processed: ```bash codegraph build -codegraph roles --role dead -T --json | node -e "const d=[];process.stdin.on('data',c=>d.push(c));process.stdin.on('end',()=>{const items=JSON.parse(Buffer.concat(d));console.log(JSON.stringify({total:items.length,byRole:items.reduce((a,i)=>{a[i.role]=(a[i.role]||0)+1;return a},{})}));})" +codegraph roles --role dead -T --json | node -e "const d=[];process.stdin.on('data',c=>d.push(c));process.stdin.on('end',()=>{const data=JSON.parse(Buffer.concat(d));console.log(JSON.stringify({total:data.count,byRole:data.summary}));})" ``` Store in `grind.deadSymbolCurrent`. Write `titan-state.json`. From 84d2491cfa6d0dce07124e5792bb275c2d98991c Mon Sep 17 00:00:00 2001 From: carlos-alm Date: Mon, 6 Jul 2026 19:09:19 -0600 Subject: [PATCH 2/2] fix: guard against parse failures in Step 0.12/4 dead-symbol one-liners (Greptile) --- .claude/skills/titan-grind/SKILL.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.claude/skills/titan-grind/SKILL.md b/.claude/skills/titan-grind/SKILL.md index f6605c53e..d1b556c59 100644 --- a/.claude/skills/titan-grind/SKILL.md +++ b/.claude/skills/titan-grind/SKILL.md @@ -109,7 +109,7 @@ Forge shapes the metal. Grind smooths the rough edges. Your goal: find helpers t 12. **Capture dead-symbol baseline** (only if `grind.deadSymbolBaseline` is null): ```bash - codegraph roles --role dead -T --json | node -e "const d=[];process.stdin.on('data',c=>d.push(c));process.stdin.on('end',()=>{const data=JSON.parse(Buffer.concat(d));console.log(JSON.stringify({total:data.count,byRole:data.summary}));})" + codegraph roles --role dead -T --json | node -e "const d=[];process.stdin.on('data',c=>d.push(c));process.stdin.on('end',()=>{try{const data=JSON.parse(Buffer.concat(d));console.log(JSON.stringify({total:data.count??0,byRole:data.summary??{}}));}catch(e){console.error('Failed to parse roles --json output: '+e.message);process.exit(1);}})" ``` `codegraph roles --json` returns `{ count, summary, symbols }` (not a bare array) — `summary` is already the per-role breakdown (e.g. `dead-leaf`, `dead-entry`, `dead-ffi`, `dead-unresolved`), so no manual reduce is needed. Store the total in `grind.deadSymbolBaseline`. Write `titan-state.json` immediately. @@ -580,7 +580,7 @@ After all targets in the phase are processed: ```bash codegraph build -codegraph roles --role dead -T --json | node -e "const d=[];process.stdin.on('data',c=>d.push(c));process.stdin.on('end',()=>{const data=JSON.parse(Buffer.concat(d));console.log(JSON.stringify({total:data.count,byRole:data.summary}));})" +codegraph roles --role dead -T --json | node -e "const d=[];process.stdin.on('data',c=>d.push(c));process.stdin.on('end',()=>{try{const data=JSON.parse(Buffer.concat(d));console.log(JSON.stringify({total:data.count??0,byRole:data.summary??{}}));}catch(e){console.error('Failed to parse roles --json output: '+e.message);process.exit(1);}})" ``` Store in `grind.deadSymbolCurrent`. Write `titan-state.json`.