Skip to content

F7: L3/L4 consumption API — shared program-slice engine + five facade verbs (slice/flows/def-use) #270

Description

@rahlk

PROBLEM

Schema v2 exposes rich L3/L4 information — per-callable CFG/CDG/DDG and the interprocedural SDG (param_in/param_out/summary) — but F6 (#244) only exposes it as raw nx graphs the user must hand-walk. This issue adds the "easy to consume" derived layer: a shared program-slice engine and five facade verbs that turn the graphs into citable slice/flow evidence.

Design: docs/superpowers/specs/2026-07-14-l3l4-consumption-api-design.md (local).

SCOPE BOUNDARY

Analysis-complete PRIMITIVES only — slices, dataflow reachability, def-use. NO taint/policy layer (sources, sinks, sanitizers, tainted-path search): that is #229 and the 2.1.0 chain's sink_pattern/without_passing_through. No new per-language analysis (the analyzers are pure graph providers). No Cypher-pushdown of traversal (client-side over nx for rc.1; pushdown parallels the chain's #217, later).

GOALS (the contract)

  1. Shared engine cldk/graph/engine.py — traversal written ONCE, language-neutral, operating on the cpg models (F2: cldk/models/cpg — canonical schema-v2 models, modeled once (layer 1) #240). Never reimplemented per language (that is the divergence bug class that shipped 4x in the 2026-07-14 audit).
  2. ABC data-provider seam on each AnalysisBackend (extending F6's additions): program_graph(callable_uri), sdg_edges(), resolve_location(file,line,col?), source_slice(vertex_uri), callable_of(vertex_uri) — implemented by every Codeanalyzer (local, from cpg) AND every Neo4jBackend (Cypher).
  3. Five facade verbs (identical on all four facades, thin delegates to Engine(self.backend)):
    slice_backward, slice_forward, flows_to, def_use, control_deps — signatures per the spec §4.
  4. Polymorphic seed: "file:line[:col]" | "can://…@line:col" | BodyNode, normalized by resolve_vertex.
  5. Result objects cldk/graph/result.py: GraphResult base (subgraph, evidence[{uri,file_line,code,role}], uris(), explain(), to_json(), len, bool); SliceResult; FlowResult (+ FlowPath == the 2.1.0 chain's PathWitness shape). Confidence read from keystone prov: ssa->structural, points-to->resolved (feat(core-models): edge confidence labels — resolved / structural / unresolved #207 vocab).
  6. Capability gating (reuse the epic model): L3 for intra slices/def_use/control_deps, L4 for flows_to/interprocedural. Honest degrade by default (label structural, record gap in explain()), strict=True raises CapabilityError. Java at rc.1 (pre-v2) degrades identically to level-2 — one path, no per-language branch.

CAVEATS AND KNOWN RISKS

DEFINITION OF DONE

  • Engine unit tests on hand-built cpg fixtures assert EXACT expected vertex sets (a backward slice == the hand-computed node set, not "non-empty").
  • Dual-backend parity contract: every Tier-1 verb, local vs Neo4j, identical results modulo documented lossiness (Neo4j code=None when source unprojected) — seeds test: generalized cross-language, cross-backend contract suite #210.
  • End-to-end assertions against the golden L3/L4 samples from cants and codeanalyzer-python.
  • All-new additive surface: F1 oracle records these methods as present; the frozen get_* facade is untouched.

Part of #238

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions