Skip to content

Learning epic: build codeanalyzer-rust to a level-3 SDG — in Rust, by hand #9

Description

@rahlk

The premise

I am learning Rust by writing the CLDK Rust analyzer in Rust — the backend-in-its-own-language
rule, taken as a curriculum. Like The Rust Programming Language book's final project (a web server
built up chapter by chapter), the issues below are sorted in escalating complexity: retire them
in order and the result is a mature codeanalyzer-rust — canonical analysis.json, Neo4j
projection, packaged releases, and finally native level-3 dataflow graphs (CFG → PDG → SDG)
with slicing and taint.

Every issue names the Rust concepts it exercises (with TRPL chapters by name) and ends in a
gate — a concrete, testable definition of done taken from the CLDK skillset's verification
criteria. The gate discipline is the pedagogy: no issue starts until the previous one's gate is
green.

What already exists (Feb 2025 scaffold)

  • src/entities/ — 1,238 LOC of thoughtful Rust-native schema types (is_async/is_unsafe,
    lifetimes, generics, SafetyAnalysis). Better than the canonical spine at the leaves; missing
    the spine itself (no signature, no symbol_table/call_graph root, no serde wiring).
  • src/main.rs — a clap CLI whose run() is an empty stub, with a --project-root-pom flag
    copy-pasted from the Java analyzer (a fossil to remove).
  • A working single-target release.yml + devcontainer.

Issue 01 starts from auditing this, not from cargo new.

Locked tooling (defaulted from the skill's recommendations — revisit before issue 04 if desired)

codeanalyzer-rust — architecture & tooling
depth: level 1 → level 3 (level 2 / MIR deliberately skipped; seam stays stubbed)
runtime: Rust (static binary via cargo)
structural: tree-sitter-rust [DEFAULTED — syn / ra_ap_syntax were the alternatives]
resolution: hand-rolled name resolution (use-map + scope chain + receiver-type inference),
upgraded by a later issue [DEFAULTED — ra_ap_hir-from-day-one was the alternative]
L3 substrate: CFG hand-built from the AST; hand-built reaching definitions;
type-based may-alias oracle (ownership makes it unusually strong: &mut is exclusive)
packaging: cargo cross-compile → GitHub Release binaries + thin PyPI wheel + brew formula
extra nodes: traits, impls, enums-with-data, macros; trait bounds → base_classes

Record the final versions of these in the README under Architecture & Tooling (issue 01) and
every schema decision in .claude/SCHEMA_DECISIONS.md (issue 02).

The contract that binds every issue

The canonical CLDK shape the sibling analyzers (canpy / cants / canclang) already emit:
Application { symbol_table: Map<relative path, Module>, call_graph: [identity-only edges] },
snake_case JSON, ONE signature_of() canonicalizer producing every id, edges that byte-match real
callable signatures, rich per-call data on Callsite.callee_signature (null → backfilled).
Reference: the cldk-forge codeanalyzer-backend skill (references/canonical-schema.md,
schema-reference.md, testing-and-validation.md, dataflow-graphs.md,
dataflow-construction.md) and codeanalyzer-clang / codeanalyzer-python as worked examples.

The ladder

Phase 0 — foundations(modules, error handling, serde, the contract)

Phase 1 — level 1(iterators, FFI parsing, ownership at scale, name resolution, testing, release engineering)

Phase 3 — level 3, native dataflow(smart pointers & arenas, graph algorithms, dataflow frameworks, fixpoints, fearless concurrency)

Out of scope, on purpose

  • Level 2 (MIR / rustc-internals framework backend): nightly-only and immature; the type-based
    oracle covers most of what it would add, because ownership already answers many alias questions.
    The semantic_analysis seam for it is scaffolded empty in issue 01.
  • Implementation by anyone but me. Agents may review, critique, and teach — not write the code.

How I work

Issue → branch (feat/issue-XXX) → work → PR, one issue at a time, in order. Each PR must show its
issue's gate passing (tests in CI). If a gate exposes a wrong earlier decision, reopen the earlier
issue rather than patching around it.

Metadata

Metadata

Assignees

Labels

EpicCross-repo coordination epicLearning

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions