Skip to content

Commit e2cc4e3

Browse files
committed
docs(design): add schema v2 + L3/L4 design spec and SCHEMA_DECISIONS ledger
Spec is point-in-time provenance; §15 links epic #42 as the live plan.
1 parent 56b044f commit e2cc4e3

2 files changed

Lines changed: 298 additions & 0 deletions

File tree

.claude/SCHEMA_DECISIONS.md

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# Schema Decisions — codeanalyzer-java
2+
3+
Living ledger of schema-design decisions, recorded per cldk-devtools
4+
`schema-design-loop.md`. Each entry: the decision, its rationale, and any
5+
divergence from the canonical keystone or the Python reference pilot. This file
6+
is kept **current** as decisions evolve during implementation; the design spec
7+
(`docs/design/specs/schema-v2-l3-l4-design.md`) is point-in-time provenance.
8+
9+
## Effort: canonical schema v2 migration + L3/L4 dataflow (2026-08)
10+
11+
Migrate `codeanalyzer-java` from legacy v1 (`{symbol_table, call_graph, version}`)
12+
to the canonical v2 CPG, and grow it to analysis level 4. Anchored on the keystone
13+
and on `codeanalyzer-python` (the v2 + L3/L4 reference pilot, on its `main`).
14+
15+
### D1 — Transition posture: pure canonical v2
16+
Drop per-callable `code` (SDK slices `module.source[span.bytes]`), drop legacy flat
17+
`start_line`/`end_line` (use `span`), and express call sites **only** as `body`
18+
`call` nodes (no `call_sites[]`). **Divergence:** the Python pilot kept those legacy
19+
fields additively for a smoother SDK transition; Java goes clean. SDK Java views
20+
reconstruct the old surface (`.code`, `.call_sites`).
21+
22+
### D2 — Annotations: structured decorators
23+
`decorators:[{name, args[], span}]`, not flat strings. Java annotations carry
24+
meaningful arguments (`@RequestMapping("/x")`, `@Column(name=…)`) needed by
25+
framework/CRUD/entrypoint analysis. **Divergence:** the Python pilot used flat
26+
`decorators:List[str]`.
27+
28+
### D3 — Metrics & cross-refs: nested per keystone
29+
`metrics:{cyclomatic}` and `refs:{types:[id], fields:[id]}`. Forward-compatible/
30+
extensible. **Divergence:** the Python pilot and current Java keep these flat
31+
(`cyclomatic_complexity`, `referenced_types`, `accessed_fields`); SDK views expose
32+
the old flat names.
33+
34+
### D4 — Type kinds: single `kind` + `nesting`
35+
`type.kind ∈ {class, interface, enum, record, annotation}` plus
36+
`nesting:{parent?, is_local?}`, replacing the v1 `is_interface`/`is_enum`/
37+
`is_record`/`is_nested`/… boolean pile.
38+
39+
### D5 — L3 CFG engine & granularity: WALA engine → source-statement nodes
40+
Use WALA as the analysis engine (`SSACFG` + dominance + SSA def-use — heap-ready for
41+
L4), but emit **source-statement-level** body nodes keyed by `line:col`: project each
42+
SSA instruction to its enclosing source statement via `IMethod.getSourcePosition` +
43+
JavaParser statement spans; fold/drop synthetic phi/pi nodes.
44+
**Fallback (recorded, not silent):** if SSA→source-statement fidelity proves
45+
unresolvable, revisit hand-building the CFG from the JavaParser AST (as Python/TS/Go do).
46+
47+
### D6 — L4 points-to precision: RTA default + `--precision`
48+
Default RTA (reuse the L2 call-graph pointer analysis; proven to scale — 0-1-CFA was
49+
found not to). Expose `--precision {rta,0-cfa,0-1-cfa}`. Coarse heap precision ⇒
50+
conservative but sound-leaning semantic `ddg`.
51+
52+
### D7 — L4 summary edges: own summary pass
53+
Compute `summary` (actual_in→actual_out) edges via a dedicated pass — hammock regions
54+
composed bottom-up over the SCC-condensation DAG (Tarjan), k-limited to a monotone
55+
fixpoint — mirroring `codeanalyzer-python` (`summaries.py`/`scc.py`). WALA's HRB
56+
summaries are lazily computed inside its Slicer and not cleanly exposable. Heaviest
57+
L4 unit; lands last.
58+
59+
### D8 — Identity: `can://java/<app>/<file>/<type>/<signature>`
60+
Java analog of the pilot's `can://python/…`; built from the existing `signatureOf()`.
61+
Ordinal ids `…@<line>:<col>` (real) / `…@<tag>` (synthetic) within a callable.
62+
63+
### D9 — Neo4j namespace: keep the `J_` relationship prefix
64+
Existing convention (`J_CALLS`, …); dual-label `JSymbol` merge pattern retained.
65+
`SchemaCatalog` takes a major bump (families rename v1→v2).
66+
67+
### Scope guard
68+
The analyzer is a **pure graph provider**: it emits the CFG/PDG/SDG substrate and
69+
stops. Slicing, taint, and reachability are **SDK queries** over the emitted graph
70+
(`cldk-sdk-frontend`) — never analyzer features. No `taint_flows` section, no
71+
sources/sinks policy in the analyzer.

0 commit comments

Comments
 (0)