Implement comprehensive dead code detection for hako_check with JoinIR integration, following Phase 133/134/152 box-based modularity pattern. ## Key Achievements 1. **Comprehensive Inventory** (`phase153_hako_check_inventory.md`): - Documented current hako_check architecture (872 lines) - Analyzed existing HC011/HC012 rules - Confirmed JoinIR-only pipeline (Phase 124) - Identified Phase 153 opportunities 2. **DeadCodeAnalyzerBox** (`rule_dead_code.hako`): - Unified HC019 rule (570+ lines) - Method-level + box-level dead code detection - DFS reachability from entrypoints - Text-based analysis (no MIR JSON dependency for MVP) - Heuristic-based false positive reduction 3. **CLI Integration** (`cli.hako`): - Added `--dead-code` flag for comprehensive mode - Added `--rules dead_code` for selective execution - Compatible with --format (text/json-lsp/dot) 4. **Test Infrastructure**: - HC019_dead_code test directory (ng/ok/expected.json) - `hako_check_deadcode_smoke.sh` with 4 test cases ## Technical Details - **Input**: Analysis IR (MapBox with methods/calls/boxes/entrypoints) - **Output**: HC019 diagnostics - **Algorithm**: Graph-based DFS reachability - **Pattern**: Box-based modular architecture - **No ENV vars**: CLI flags only ## Files Modified - NEW: docs/development/current/main/phase153_hako_check_inventory.md - NEW: tools/hako_check/rules/rule_dead_code.hako - MOD: tools/hako_check/cli.hako - NEW: tools/hako_check/tests/HC019_dead_code/ - NEW: tools/hako_check_deadcode_smoke.sh - MOD: CURRENT_TASK.md ## Next Steps - Phase 154+: MIR CFG integration for block-level detection - Phase 160+: Integration with .hako JoinIR/MIR migration 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Hako Check — Diagnostics Contract (MVP)
This tool lints .hako sources and emits diagnostics.
Diagnostics schema (typed)
- Map fields:
rule: string like "HC011"message: string (human-readable, one line)file: string (path)line: int (1-based)severity: string ("error"|"warning"|"info"), optional (default: warning)quickFix: string, optional
Backwards compatibility
- Rules may still
out.push("[HCxxx] ...")with a single-line string. - The CLI accepts both forms. String diagnostics are converted to typed internally.
Suppression policy
- HC012 (dead static box) takes precedence over HC011 (unreachable method).
- If a box is reported by HC012, HC011 diagnostics for methods in that box are suppressed at aggregation.
Quiet / JSON output
- When
--format json-lspis used, output is pure JSON (pretty). Combine withNYASH_JSON_ONLY=1in the runner to avoid extra lines. - Non-JSON formats print human-readable lines per finding.
Planned AST metadata (parser_core.hako)
boxes[].span_line: starting line of thestatic boxdeclaration.methods[].arity: parameter count as an integer.boxes[].is_static: boolean.
Notes
- Prefer AST intake; text scans are a minimal fallback.
- For tests, use
tools/hako_check/run_tests.sh.
Analyzer policy (plugins)
- Tests/CI/Analyzer run without plugins by default:
NYASH_DISABLE_PLUGINS=1andNYASH_JSON_ONLY=1. - File I/O is avoided by passing source text via
--source-file <path> <text>. - When plugins are needed (dev/prod), set
NYASH_FILEBOX_MODE=autoand provide [libraries] in nyash.toml.
Default test env (recommended)
NYASH_DISABLE_PLUGINS=1– avoid dynamic plugin path and noiseNYASH_BOX_FACTORY_POLICY=builtin_first– prefer builtin/ring‑1 for stabilityNYASH_DISABLE_NY_COMPILER=1andHAKO_DISABLE_NY_COMPILER=1– disable inline compiler in testsNYASH_JSON_ONLY=1– stdout is pure JSON (logs go to stderr)
Known Limitations
HC017: Non-ASCII Quotes Detection (Temporarily Skipped)
Status: ⏸️ Skipped until UTF-8 support is available
Reason: This rule requires UTF-8 byte-level manipulation to detect smart quotes (" " ' ') in source code. Nyash currently lacks:
- Byte array access for UTF-8 encoded strings
- UTF-8 sequence detection capabilities (e.g., detecting 0xE2 0x80 0x9C for ")
- Unicode character property inspection methods
Technical Requirements: One of the following implementations is needed:
- Implement
ByteArrayBoxwith UTF-8 encoding/decoding methods (to_bytes(),from_bytes()) - Add built-in Unicode character property methods to
StringBox(e.g.,is_ascii(),char_code_at()) - Provide low-level byte access methods like
string.get_byte(index)orstring.byte_length()
Re-enable Timeline: Planned for Phase 22 (Unicode Support Phase) or when ByteArrayBox lands
Test Files:
tests/HC017_non_ascii_quotes/ng.hako- Contains intentional smart quotes for detection testingtests/HC017_non_ascii_quotes/ok.hako- Clean code without smart quotes (baseline)tests/HC017_non_ascii_quotes/expected.json- Empty diagnostics (reflects disabled state)
Implementation File: rules/rule_non_ascii_quotes.hako - Currently returns 0 (disabled) in _has_fancy_quote()
Current Workaround: The test is automatically skipped in run_tests.sh to prevent CI failures until UTF-8 support is implemented.
Rules
- Core implemented (green): HC011 Dead Methods, HC012 Dead Static Box, HC015 Arity Mismatch, HC016 Unused Alias, HC018 Top‑level local, HC021 Analyzer IO Safety, HC022 Stage‑3 Gate, HC031 Brace Heuristics
- Temporarily skipped: HC017 Non‑ASCII Quotes (UTF-8 support required)
- Pending fixtures update: HC013 Duplicate Method, HC014 Missing Entrypoint
CLI options
--rules a,b,climit execution to selected rules.--skip-rules a,bskip selected.--no-ast(default) avoids AST parser;--force-astenables AST path (use sparingly while PHI is under polish).
Tips
- JSON-only output: set
NYASH_JSON_ONLY=1to avoid log noise in stdout; diagnostics go to stdout, logs to stderr. - For multiline
--source-filepayloads, CLI also provides HEX-escaped JSON inNYASH_SCRIPT_ARGS_HEX_JSONfor robust transport; the VM prefers HEX→JSON→ARGV.